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

# Create a webhook

> Create a webhook that receives the job events of every job you could see, the jobs you start from any client (the Dashboard, an MCP client or an API key), and return its signing secret once. Every member can make webhooks, and only you change, test and rotate yours; a Business Owner or Admin also sees and may delete them. Deliveries are signed with Standard Webhooks (webhook-id, webhook-timestamp, webhook-signature), retried for about 15 minutes, and sent only to public HTTPS addresses. The webhook keeps working if you leave the team. Without events it receives all four. Events: job.needs_input (a job asks a question; the payload has its screened questions and the page where you answer), job.input_expiring (three minutes left to answer), job.succeeded and job.failed (a job settled). No event carries a result: read it from the job through the client that started it. You can hold at most 20 webhooks.



## OpenAPI

````yaml /api-reference/openapi.json post /v1/webhooks
openapi: 3.1.0
info:
  title: Pomerado API
  version: '1'
  description: >-
    Run and build website tools, follow their jobs, and manage logins, API keys
    and webhooks. Authenticate with a Pomerado API key (pom_…), an MCP OAuth
    token or a Dashboard session as a Bearer token.
servers:
  - url: https://api.pomerado.ai
security: []
tags:
  - name: api_keys
    x-group: API keys
  - name: webhooks
    x-group: Webhooks
paths:
  /v1/webhooks:
    post:
      tags:
        - webhooks
      summary: Create a webhook
      description: >-
        Create a webhook that receives the job events of every job you could
        see, the jobs you start from any client (the Dashboard, an MCP client or
        an API key), and return its signing secret once. Every member can make
        webhooks, and only you change, test and rotate yours; a Business Owner
        or Admin also sees and may delete them. Deliveries are signed with
        Standard Webhooks (webhook-id, webhook-timestamp, webhook-signature),
        retried for about 15 minutes, and sent only to public HTTPS addresses.
        The webhook keeps working if you leave the team. Without events it
        receives all four. Events: job.needs_input (a job asks a question; the
        payload has its screened questions and the page where you answer),
        job.input_expiring (three minutes left to answer), job.succeeded and
        job.failed (a job settled). No event carries a result: read it from the
        job through the client that started it. You can hold at most 20
        webhooks.
      operationId: webhooks.create
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - url
              properties:
                url:
                  type: string
                events:
                  type: array
                  items:
                    type: string
                    enum:
                      - job.needs_input
                      - job.input_expiring
                      - job.succeeded
                      - job.failed
                  description: an array of at least 1 item(s)
                  minItems: 1
              additionalProperties: false
      responses:
        '201':
          description: The new webhook and its one-time secret
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WebhookWithSecret'
        '400':
          description: invalid_request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: unauthorized, reauthentication_required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: webhooks_unavailable, forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '409':
          description: webhook_limit_reached
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '413':
          description: request_too_large
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: internal_error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '503':
          description: temporarily_unavailable
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
      security:
        - bearer: []
components:
  schemas:
    WebhookWithSecret:
      type: object
      required:
        - id
        - created_by
        - url
        - events
        - status
        - disabled_reason
        - created_at
        - last_delivery_at
        - secret
      properties:
        id:
          $ref: '#/components/schemas/webhook_id'
        created_by:
          $ref: '#/components/schemas/WebhookCreator'
        url:
          type: string
        events:
          type: array
          items:
            type: string
            enum:
              - job.needs_input
              - job.input_expiring
              - job.succeeded
              - job.failed
        status:
          type: string
          enum:
            - active
            - disabled
        disabled_reason:
          anyOf:
            - type: string
              enum:
                - manual
                - gone
                - unreachable
                - secret_unreadable
            - type: 'null'
          description: >-
            Why a disabled webhook sends nothing: manual (turned off), gone (its
            receiver answered 410), unreachable (20 failed deliveries in a row)
            or secret_unreadable (rotate its secret)
        created_at:
          $ref: '#/components/schemas/Date'
        last_delivery_at:
          anyOf:
            - $ref: '#/components/schemas/Date'
            - type: 'null'
        secret:
          type: string
          description: >-
            The Standard Webhooks signing secret (whsec_…), shown in this answer
            only. Verify each delivery's webhook-signature with it.
      additionalProperties: false
    Error:
      type: object
      required:
        - error
      properties:
        error:
          type: object
          required:
            - code
            - message
            - retryable
            - docs_url
          properties:
            code:
              type: string
            message:
              type: string
            retryable:
              type: boolean
            docs_url:
              type: string
            details:
              type: object
              required: []
              properties: {}
              additionalProperties:
                $id: /schemas/unknown
          additionalProperties: false
      additionalProperties: false
    webhook_id:
      type: string
      description: 'a webhook ID: wh_ and 32 lowercase hex digits'
      examples:
        - wh_0f8e2d1c4b3a49e8a7f6e5d4c3b2a190
    WebhookCreator:
      type: object
      required:
        - user_id
        - email
      properties:
        user_id:
          type: string
          description: The member's user ID
        email:
          anyOf:
            - type: string
            - type: 'null'
          description: >-
            The email they sign in with, or null when the account no longer has
            it
      additionalProperties: false
      description: >-
        The member who made the webhook: only they change, test and rotate it,
        and it carries the events of the jobs they could see
    Date:
      type: string
      description: a string to be decoded into a Date
  securitySchemes:
    bearer:
      type: http
      scheme: bearer

````

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