> ## Documentation Index
> Fetch the complete documentation index at: https://docs.nohead.io/llms.txt
> Use this file to discover all available pages before exploring further.

# List webhooks

> The project's webhooks. With `filter[deleted]=true`, the deleted ones, until they are purged.



## OpenAPI

````yaml /openapi.json get /v1/projects/{project_id}/webhooks
openapi: 3.1.1
info:
  title: Nohead API
  version: 1.0.0
  summary: Programmable content and data API.
  contact:
    name: Nohead
    email: hello@nohead.io
    url: https://nohead.io
  description: >
    The Nohead API manages projects, collections (your data models), their

    fields, and records (your content), with full version history.


    ## Authentication


    Send `Authorization: Bearer <token>`. Servers, CI and agents use a

    project API key (`nohead_sk_...`, or `nohead_pk_...` for a published-only

    key; created in the web app under API keys)

    with scopes such as `records:read` or `schema:write`. Organization,

    project, member and API key management need a person signed in to the

    web app and are not available to API keys.


    ## Resources and IDs


    Every object has an `object` type, and every resource with an identity of

    its own an opaque, prefixed `id` (`col_`, `fld_`, `rec_`, ...). Record
    values live under `data`, keyed by each

    field's `key`. Timestamps are ISO 8601 in UTC. Deleting a record,

    collection, field, asset or webhook is soft: it can be restored until its

    `purge_after`.


    ## Lists


    Lists return `{ "data": [...], "meta": { "next_cursor", "has_more" } }`.

    Pass `limit` (1-100) and `cursor` to page, and `sort` (prefix `-` for

    descending). Records also take `filter[<key>]=value`,

    `filter[published_at][exists]=true` and `expand=<relation, asset or

    rich text fields>`.


    ## Errors


    Errors share one envelope: `{ "error": { "type", "message",

    "request_id", "details" } }`. `details` lists field-level problems as

    `{ "field", "code", "message" }`. Include the `request_id` when asking

    for support.


    ## Safe retries and concurrent edits


    Send `Idempotency-Key` on any `POST`, `PUT`, `PATCH` or `DELETE` to make
    retrying

    it safe: the first result is stored for 24 hours and returned again for

    the same request. Record responses carry the record's revision as an

    `ETag`; send it back as `If-Match` to update only if nobody changed the

    record in the meantime (`412` otherwise).


    ## History


    Every change to a record is a revision, attributed to the person or API

    key that made it: record revisions can be listed, diffed and reverted,

    and collections keep a schema history. Send `Nohead-Change-Note` to

    record why a change was made. Changes that rewrite existing values

    (such as a field's type) are explicit, previewable field migrations.


    How long revisions are kept depends on the organization's plan. Older

    ones are removed, but every record keeps its first revision and its

    last 10; `history_pruned_through` says how far history was removed.
  license:
    name: Proprietary
    identifier: LicenseRef-Proprietary
servers:
  - url: https://api.nohead.io
    description: Production
security:
  - apiKey: []
tags:
  - name: records
    x-group: Records
    description: Content entries, one at a time or many at once.
  - name: publishing
    x-group: Publishing
    description: Making records live, now or at a set time, and taking them down.
  - name: revisions
    x-group: Revisions
    description: A record's history, comparing two revisions, and going back to one.
  - name: drafts
    x-group: Drafts
    description: Changes to a record that wait to be merged into it, now or at a set time.
  - name: collections
    x-group: Collections
    description: User-defined data models.
  - name: schema-changes
    x-group: Schema changes
    description: A collection's schema history, and its schema at any version.
  - name: fields
    x-group: Fields
    description: Field definitions of a collection.
  - name: migrations
    x-group: Field migrations
    description: Explicit field changes that rewrite existing record values, with previews.
  - name: assets
    x-group: Assets
    description: Files stored for a project, uploaded directly to storage.
  - name: search
    x-group: Search
    description: Full-text search in collections and across a project.
  - name: webhooks
    x-group: Webhooks
    description: Event notifications sent to your URLs, and the secrets that sign them.
  - name: deliveries
    x-group: Webhook deliveries
    description: Each event sent to a webhook, its attempts, and retrying it.
  - name: audit
    x-group: Activity log
    description: The append-only trail of who changed what, through which client.
  - name: system
    x-group: System
    description: Service status, the caller, and its feature flags.
paths:
  /v1/projects/{project_id}/webhooks:
    parameters:
      - $ref: '#/components/parameters/ProjectId'
    get:
      tags:
        - webhooks
      summary: List webhooks
      description: >-
        The project's webhooks. With `filter[deleted]=true`, the deleted ones,
        until they are purged.
      operationId: webhooks_list
      parameters:
        - $ref: '#/components/parameters/DeletedFilter'
        - $ref: '#/components/parameters/Limit'
        - $ref: '#/components/parameters/Cursor'
      responses:
        '200':
          description: A page of webhooks.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WebhookList'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/RateLimited'
      x-codeSamples:
        - lang: typescript
          label: TypeScript
          source: >
            import { Nohead } from "@nohead/sdk"


            const nohead = new Nohead()


            for await (const webhook of nohead.webhooks.list({ deleted: true }))
            {
              console.log(webhook)
            }
        - lang: python
          label: Python
          source: |
            from nohead import Nohead

            nohead = Nohead()

            for webhook in nohead.webhooks.list(deleted=True):
                print(webhook)
        - lang: ruby
          label: Ruby
          source: |
            require "nohead"

            nohead = Nohead::Client.new

            nohead.webhooks.list(deleted: true).each do |webhook|
              puts webhook
            end
components:
  parameters:
    ProjectId:
      name: project_id
      in: path
      required: true
      schema:
        type: string
      example: prj_01J9ZQ3F8X5W2K7M4N6P0R1S2T
    DeletedFilter:
      name: filter
      in: query
      style: deepObject
      explode: true
      description: '`filter[deleted]=true` lists soft-deleted items instead of active ones.'
      schema:
        type: object
        additionalProperties: false
        properties:
          deleted:
            type: string
            enum:
              - 'true'
              - 'false'
    Limit:
      name: limit
      in: query
      description: Page size.
      schema:
        type: integer
        minimum: 1
        maximum: 100
        default: 20
    Cursor:
      name: cursor
      in: query
      description: The `next_cursor` from the previous page.
      schema:
        type: string
  schemas:
    WebhookList:
      type: object
      additionalProperties: false
      required:
        - data
        - meta
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/Webhook'
        meta:
          $ref: '#/components/schemas/ListMeta'
    Webhook:
      allOf:
        - $ref: '#/components/schemas/WebhookProperties'
      unevaluatedProperties: false
    ListMeta:
      type: object
      description: Cursor pagination metadata returned with every list.
      additionalProperties: false
      required:
        - next_cursor
        - has_more
      properties:
        next_cursor:
          type:
            - string
            - 'null'
          description: Opaque cursor for the next page, or null on the last page.
        has_more:
          type: boolean
    Error:
      type: object
      additionalProperties: false
      required:
        - error
      properties:
        error:
          type: object
          additionalProperties: false
          required:
            - type
            - message
            - request_id
          properties:
            type:
              $ref: '#/components/schemas/ErrorType'
            message:
              type: string
            request_id:
              $ref: '#/components/schemas/RequestId'
            details:
              type: array
              items:
                $ref: '#/components/schemas/ErrorDetail'
    WebhookProperties:
      type: object
      required:
        - id
        - object
        - project_id
        - url
        - description
        - event_types
        - published_only
        - enabled
        - deleted_at
        - purge_after
        - created_at
        - updated_at
      properties:
        id:
          type: string
          examples:
            - wh_01J9ZQ3F8X5W2K7M4N6P0R1S2T
        object:
          const: webhook
        project_id:
          type: string
        url:
          type: string
          format: uri
        description:
          type:
            - string
            - 'null'
        event_types:
          type: array
          description: >-
            The subscribed event types and wildcards (`record.*`, or `*` for
            all).
          items:
            $ref: '#/components/schemas/WebhookSubscription'
        published_only:
          type: boolean
          description: >-
            Send only events that change what a published-only API key can read:
            a record's change while it is published (or that publishes,
            unpublishes, deletes or restores it), schema changes, and changes to
            assets that published records use. Drafts, schedules, history
            redactions, uploads and purges are never sent. `webhook.test` always
            is.
        enabled:
          type: boolean
        deleted_at:
          $ref: '#/components/schemas/NullableTimestamp'
          description: When the webhook was deleted; null unless it is.
        purge_after:
          $ref: '#/components/schemas/NullableTimestamp'
          description: >-
            When a deleted webhook is removed for good, with its delivery log,
            unless restored first.
        created_at:
          $ref: '#/components/schemas/Timestamp'
        updated_at:
          $ref: '#/components/schemas/Timestamp'
    RequestId:
      type: string
      pattern: ^req_[A-Za-z0-9]+$
      examples:
        - req_01J9ZQ3F8X5W2K7M4N6P0R1S2T
    ErrorType:
      type: string
      enum:
        - invalid_request
        - authentication_error
        - plan_limit_exceeded
        - authorization_error
        - not_found
        - conflict
        - precondition_failed
        - validation_error
        - rate_limited
        - internal_error
        - service_unavailable
    ErrorDetail:
      type: object
      additionalProperties: false
      required:
        - code
        - message
      properties:
        field:
          type: string
          description: Key of the offending field or parameter, when applicable.
        code:
          type: string
          description: Machine-readable error code, e.g. `required`.
        message:
          type: string
        usage:
          type: integer
          description: Current usage, for `plan_limit` details.
        limit:
          type: integer
          description: The plan's limit, for `plan_limit` details.
        current_revision:
          type: integer
          description: The resource's current revision, for `revision_mismatch` details.
        record_id:
          type: string
          description: The record that already has the value, for `taken` details.
        draft_id:
          type: string
          description: The record's draft, for `draft_exists` and `draft_pending` details.
    WebhookSubscription:
      anyOf:
        - $ref: '#/components/schemas/WebhookEventType'
        - type: string
          enum:
            - record.*
            - draft.*
            - collection.*
            - field.*
            - asset.*
            - '*'
    NullableTimestamp:
      type:
        - string
        - 'null'
      format: date-time
    Timestamp:
      type: string
      format: date-time
      description: ISO 8601 timestamp in UTC.
      examples:
        - '2026-09-27T12:00:00.000Z'
    WebhookEventType:
      type: string
      description: >
        An event webhooks can subscribe to: the same names as the activity

        log's actions. A subscription can also be every type of a resource

        (`record.*`, `draft.*`, `collection.*`, `field.*`, `asset.*`) or `*` for
        all.
      enum:
        - record.created
        - record.updated
        - record.published
        - record.unpublished
        - record.deleted
        - record.restored
        - record.reverted
        - record.redacted
        - record.scheduled
        - record.unscheduled
        - record.schedule_failed
        - draft.created
        - draft.updated
        - draft.discarded
        - draft.scheduled
        - draft.unscheduled
        - draft.schedule_failed
        - collection.created
        - collection.updated
        - collection.deleted
        - collection.restored
        - collection.fields_reordered
        - field.created
        - field.updated
        - field.deleted
        - field.restored
        - field.migrated
        - field.alias_removed
        - asset.created
        - asset.updated
        - asset.deleted
        - asset.restored
        - asset.purged
  responses:
    BadRequest:
      description: >-
        The request was malformed: unparseable JSON, an invalid query parameter,
        or a body key the operation doesn't take (detail code
        `unknown_parameter`, naming the key).
      headers:
        X-Request-Id:
          $ref: '#/components/headers/RequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    Unauthorized:
      description: Authentication is missing or invalid.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/RequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    Forbidden:
      description: The caller is not allowed to perform this action.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/RequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    NotFound:
      description: The resource does not exist or is not visible to the caller.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/RequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    RateLimited:
      description: >
        Too many requests for this API key or user (or, with failing

        credentials, this IP address). A published-only key is counted per

        client IP. Wait `Retry-After` seconds; retries with the same
        `Idempotency-Key`

        are safe. On the Free plan, an organization's API keys are also

        refused once its API requests reach the month's limit, with a

        `plan_limit` detail (`field` `api_requests`, `usage` and `limit`),

        until the next month (UTC) or an upgrade.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/RequestId'
        Retry-After:
          description: Seconds to wait before retrying.
          schema:
            type: integer
        RateLimit-Limit:
          $ref: '#/components/headers/RateLimitLimit'
        RateLimit-Remaining:
          $ref: '#/components/headers/RateLimitRemaining'
        RateLimit-Reset:
          $ref: '#/components/headers/RateLimitReset'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
  headers:
    RequestId:
      description: Unique identifier for the request, also echoed in error bodies.
      schema:
        $ref: '#/components/schemas/RequestId'
    RateLimitLimit:
      description: >-
        Requests allowed in the current window. Sent on every authenticated
        response.
      schema:
        type: integer
    RateLimitRemaining:
      description: Requests left in the current window.
      schema:
        type: integer
    RateLimitReset:
      description: Seconds until the window resets.
      schema:
        type: integer
  securitySchemes:
    apiKey:
      type: http
      scheme: bearer
      description: |
        Project-scoped API key, e.g. `nohead_sk_k7fz0a9c3m2q_<secret>`, or
        `nohead_pk_…` for a published-only key. Used by servers, CI, the CLI
        and coding agents.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.