Indraft Webhooks API

The webhooks API from Indraft — 4 operation(s) for webhooks.

GitHub OpenAPI

Operations 5

GET /v1/webhooks List registered webhook endpoints #
POST /v1/webhooks Register a webhook endpoint, returning its signing secret once #
DELETE /v1/webhooks/{id} Disable a webhook endpoint #
GET /v1/webhooks/deliveries Recent delivery attempts and their outcomes #
POST /v1/webhooks/events/{id}/replay Queue an event for delivery again #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/indraft-io:indraft-io-webhooks-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

indraft-io-webhooks-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Indraft Io Webhooks API
  version: '1'
  description: 'Operations tagged webhooks across 2 of this provider''s published API definitions: indraft-io-openapi.json, indraft-io.json. Each path carries the servers of the definition it was published in.'
servers:
- url: https://api.indraft.io
security:
- bearerAuth: []
tags:
- name: Webhooks
paths:
  /v1/webhooks:
    get:
      summary: List registered webhook endpoints
      description: 'Registered endpoints and the events each is subscribed to. Signing secrets are not included: they are shown once, at registration, and rolled rather than recovered.'
      tags:
      - Webhooks
      operationId: get_v1_webhooks
      x-indraft-capability: crm:configure
      x-indraft-scopes:
      - crm:configure
      - crm:admin
      responses:
        '200':
          description: Success
          headers:
            ratelimit-limit:
              description: Requests permitted in the window closest to refusing this caller.
              schema:
                type: integer
            ratelimit-remaining:
              description: Requests left in that window. Zero means the next request is refused.
              schema:
                type: integer
            ratelimit-reset:
              description: Seconds until that window resets.
              schema:
                type: integer
            ratelimit-policy:
              description: Every window in force, not only the one reported above.
              schema:
                type: string
          content:
            application/json:
              schema:
                type: object
                properties:
                  endpoints:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: string
                        url:
                          type: string
                        events:
                          type: array
                          items:
                            type: string
                        description:
                          type: string
                        createdAt:
                          type: string
                        disabledAt:
                          type: string
                      required:
                      - id
                      - url
                      - events
                      - description
                      - createdAt
                      - disabledAt
                      additionalProperties: true
                  requestId:
                    type: string
                required:
                - endpoints
                - requestId
                additionalProperties: true
        '401':
          description: No credential, or one that has been revoked.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: Authenticated, and this capability is not held.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          description: Infrastructure protection tripped. This is not a product quota.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
          headers:
            ratelimit-limit:
              description: Requests permitted in the window closest to refusing this caller.
              schema:
                type: integer
            ratelimit-remaining:
              description: Requests left in that window. Zero means the next request is refused.
              schema:
                type: integer
            ratelimit-reset:
              description: Seconds until that window resets.
              schema:
                type: integer
            ratelimit-policy:
              description: Every window in force, not only the one reported above.
              schema:
                type: string
            retry-after:
              description: Seconds to wait before retrying. The request itself was fine.
              schema:
                type: integer
        '500':
          description: A defect on our side. The hint says so, and carries an incident id.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
    post:
      summary: Register a webhook endpoint, returning its signing secret once
      description: The signing secret is in this response and nowhere else. Verify a delivery by recomputing the signature over the timestamp and the raw body. An address that is not https, or one on a private, loopback or cloud-metadata range, is refused here rather than at delivery time.
      tags:
      - Webhooks
      operationId: post_v1_webhooks
      x-indraft-capability: crm:configure
      x-indraft-scopes:
      - crm:configure
      - crm:admin
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                url:
                  type: string
                  maxLength: 2000
                events:
                  type: array
                  items:
                    anyOf:
                    - type: string
                      enum:
                      - advance_opportunity
                      - configure_watch
                      - advance_custom_record
                      - archive
                      - restore
                      - archive_custom_record
                      - cancel_task
                      - update_task
                      - complete_task
                      - configure_custom_field
                      - configure_exchange_rate
                      - configure_object_type
                      - configure_pipeline
                      - configure_workspace
                      - set_standing_override_policy
                      - confirm
                      - create_opportunity
                      - create_task
                      - erase_subject
                      - link_contact_company
                      - merge_companies
                      - merge_contacts
                      - merge_object_records
                      - record_interaction
                      - revert_change
                      - unmerge
                      - update_opportunity
                      - upsert_company
                      - upsert_contact
                      - upsert_custom_record
                    - type: string
                      enum:
                      - watch_fired
                  maxItems: 50
                description:
                  type: string
                  maxLength: 200
              required:
              - url
              additionalProperties: false
      responses:
        '200':
          description: Success
          headers:
            ratelimit-limit:
              description: Requests permitted in the window closest to refusing this caller.
              schema:
                type: integer
            ratelimit-remaining:
              description: Requests left in that window. Zero means the next request is refused.
              schema:
                type: integer
            ratelimit-reset:
              description: Seconds until that window resets.
              schema:
                type: integer
            ratelimit-policy:
              description: Every window in force, not only the one reported above.
              schema:
                type: string
          content:
            application/json:
              schema:
                type: object
                properties:
                  endpoint:
                    type: object
                    properties:
                      id:
                        type: string
                      url:
                        type: string
                      events:
                        type: array
                        items:
                          type: string
                      description:
                        type: string
                      createdAt:
                        type: string
                      disabledAt:
                        type: string
                    required:
                    - id
                    - url
                    - events
                    - description
                    - createdAt
                    - disabledAt
                    additionalProperties: true
                  secret:
                    type: string
                  requestId:
                    type: string
                required:
                - endpoint
                - secret
                - requestId
                additionalProperties: true
        '401':
          description: No credential, or one that has been revoked.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '402':
          description: A product quota is spent, or the subscription is not active.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: Authenticated, and this capability is not held.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '409':
          description: 'A conflict the caller can resolve: a stale expectedVersion, an idempotency key reused for different input, an ambiguous or duplicate identity, or a merge that no longer applies.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '413':
          description: The body, or a single record inside it, exceeds its bound.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '422':
          description: The request does not satisfy the schema on this page.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          description: Infrastructure protection tripped. This is not a product quota.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
          headers:
            ratelimit-limit:
              description: Requests permitted in the window closest to refusing this caller.
              schema:
                type: integer
            ratelimit-remaining:
              description: Requests left in that window. Zero means the next request is refused.
              schema:
                type: integer
            ratelimit-reset:
              description: Seconds until that window resets.
              schema:
                type: integer
            ratelimit-policy:
              description: Every window in force, not only the one reported above.
              schema:
                type: string
            retry-after:
              description: Seconds to wait before retrying. The request itself was fine.
              schema:
                type: integer
        '500':
          description: A defect on our side. The hint says so, and carries an incident id.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '507':
          description: The workspace is at its storage ceiling.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
    servers:
    - url: https://api.indraft.io
  /v1/webhooks/{id}:
    delete:
      summary: Disable a webhook endpoint
      description: Disables the endpoint and keeps its delivery history, so a failure you are still investigating does not disappear when you stop the bleeding.
      tags:
      - Webhooks
      operationId: delete_v1_webhooks__id_
      x-indraft-capability: crm:configure
      x-indraft-scopes:
      - crm:configure
      - crm:admin
      parameters:
      - name: id
        in: path
        required: true
        description: The webhook id, as returned by the call that created or matched it.
        schema:
          type: string
      responses:
        '200':
          description: Success
          headers:
            ratelimit-limit:
              description: Requests permitted in the window closest to refusing this caller.
              schema:
                type: integer
            ratelimit-remaining:
              description: Requests left in that window. Zero means the next request is refused.
              schema:
                type: integer
            ratelimit-reset:
              description: Seconds until that window resets.
              schema:
                type: integer
            ratelimit-policy:
              description: Every window in force, not only the one reported above.
              schema:
                type: string
          content:
            application/json:
              schema:
                type: object
                properties:
                  disabled:
                    type: boolean
                  requestId:
                    type: string
                required:
                - disabled
                - requestId
                additionalProperties: true
        '401':
          description: No credential, or one that has been revoked.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '402':
          description: A product quota is spent, or the subscription is not active.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: Authenticated, and this capability is not held.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: No such record, or it belongs to another workspace.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '409':
          description: 'A conflict the caller can resolve: a stale expectedVersion, an idempotency key reused for different input, an ambiguous or duplicate identity, or a merge that no longer applies.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          description: Infrastructure protection tripped. This is not a product quota.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
          headers:
            ratelimit-limit:
              description: Requests permitted in the window closest to refusing this caller.
              schema:
                type: integer
            ratelimit-remaining:
              description: Requests left in that window. Zero means the next request is refused.
              schema:
                type: integer
            ratelimit-reset:
              description: Seconds until that window resets.
              schema:
                type: integer
            ratelimit-policy:
              description: Every window in force, not only the one reported above.
              schema:
                type: string
            retry-after:
              description: Seconds to wait before retrying. The request itself was fine.
              schema:
                type: integer
        '500':
          description: A defect on our side. The hint says so, and carries an incident id.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '507':
          description: The workspace is at its storage ceiling.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
    servers:
    - url: https://api.indraft.io
  /v1/webhooks/deliveries:
    get:
      summary: Recent delivery attempts and their outcomes
      description: Every attempt, its response status, how many attempts have been made and when the next one is due. This is the first place to look when a workflow stopped running, and usually the last.
      tags:
      - Webhooks
      operationId: get_v1_webhooks_deliveries
      x-indraft-capability: crm:read
      x-indraft-scopes:
      - crm:read
      - crm:write
      - crm:configure
      - crm:admin
      - crm:revert
      - data:export
      responses:
        '200':
          description: Success
          headers:
            ratelimit-limit:
              description: Requests permitted in the window closest to refusing this caller.
              schema:
                type: integer
            ratelimit-remaining:
              description: Requests left in that window. Zero means the next request is refused.
              schema:
                type: integer
            ratelimit-reset:
              description: Seconds until that window resets.
              schema:
                type: integer
            ratelimit-policy:
              description: Every window in force, not only the one reported above.
              schema:
                type: string
          content:
            application/json:
              schema:
                type: object
                properties:
                  deliveries:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: string
                        eventId:
                          type: string
                        endpointId:
                          type: string
                        status:
                          type: string
                          enum:
                          - pending
                          - delivered
                          - failed
                          - exhausted
                        attempts:
                          type: integer
                        nextAttemptAt:
                          type: string
                        responseStatus:
                          type: integer
                        error:
                          type: string
                        deliveredAt:
                          type: string
                        createdAt:
                          type: string
                        updatedAt:
                          type: string
                      required:
                      - id
                      - eventId
                      - endpointId
                      - status
                      - attempts
                      - nextAttemptAt
                      - responseStatus
                      - error
                      - deliveredAt
                      - createdAt
                      - updatedAt
                      additionalProperties: true
                  requestId:
                    type: string
                required:
                - deliveries
                - requestId
                additionalProperties: true
        '401':
          description: No credential, or one that has been revoked.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: Authenticated, and this capability is not held.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          description: Infrastructure protection tripped. This is not a product quota.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
          headers:
            ratelimit-limit:
              description: Requests permitted in the window closest to refusing this caller.
              schema:
                type: integer
            ratelimit-remaining:
              description: Requests left in that window. Zero means the next request is refused.
              schema:
                type: integer
            ratelimit-reset:
              description: Seconds until that window resets.
              schema:
                type: integer
            ratelimit-policy:
              description: Every window in force, not only the one reported above.
              schema:
                type: string
            retry-after:
              description: Seconds to wait before retrying. The request itself was fine.
              schema:
                type: integer
        '500':
          description: A defect on our side. The hint says so, and carries an incident id.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
    servers:
    - url: https://api.indraft.io
  /v1/webhooks/events/{id}/replay:
    post:
      summary: Queue an event for delivery again
      description: Queues one event to a subscribed endpoint again. Per endpoint, so replaying to a workflow you have just fixed does not re-deliver to the three that were fine.
      tags:
      - Webhooks
      operationId: post_v1_webhooks_events__id__replay
      x-indraft-capability: crm:configure
      x-indraft-scopes:
      - crm:configure
      - crm:admin
      parameters:
      - name: id
        in: path
        required: true
        description: The event id, as returned by the call that created or matched it.
        schema:
          type: string
      responses:
        '200':
          description: Success
          headers:
            ratelimit-limit:
              description: Requests permitted in the window closest to refusing this caller.
              schema:
                type: integer
            ratelimit-remaining:
              description: Requests left in that window. Zero means the next request is refused.
              schema:
                type: integer
            ratelimit-reset:
              description: Seconds until that window resets.
              schema:
                type: integer
            ratelimit-policy:
              description: Every window in force, not only the one reported above.
              schema:
                type: string
          content:
            application/json:
              schema:
                type: object
                properties:
                  queued:
                    type: integer
                  requestId:
                    type: string
                required:
                - queued
                - requestId
                additionalProperties: true
        '401':
          description: No credential, or one that has been revoked.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '402':
          description: A product quota is spent, or the subscription is not active.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: Authenticated, and this capability is not held.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: No such record, or it belongs to another workspace.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '409':
          description: 'A conflict the caller can resolve: a stale expectedVersion, an idempotency key reused for different input, an ambiguous or duplicate identity, or a merge that no longer applies.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          description: Infrastructure protection tripped. This is not a product quota.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
          headers:
            ratelimit-limit:
              description: Requests permitted in the window closest to refusing this caller.
              schema:
                type: integer
            ratelimit-remaining:
              description: Requests left in that window. Zero means the next request is refused.
              schema:
                type: integer
            ratelimit-reset:
              description: Seconds until that window resets.
              schema:
                type: integer
            ratelimit-policy:
              description: Every window in force, not only the one reported above.
              schema:
                type: string
            retry-after:
              description: Seconds to wait before retrying. The request itself was fine.
              schema:
                type: integer
        '500':
          description: A defect on our side. The hint says so, and carries an incident id.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '507':
          description: The workspace is at its storage ceiling.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
    servers:
    - url: https://api.indraft.io
components:
  schemas:
    ErrorDetail:
      type: object
      additionalProperties: true
      description: The structured payload a recovery needs. Its shape differs per code; the keys below are the ones that recur, and anything else a code carries is present alongside them.
      properties:
        fieldErrors:
          type: object
          additionalProperties:
            type: string
          description: One message per field the caller sent, keyed by that field. The key `(body)` is the request body itself, which is what an unrecognised key reports under.
        reason:
          type: string
          description: One sentence, where the refusal is about the request rather than a field. A refusal that names alternatives puts them here.
        available:
          type: array
          items:
            type: string
          description: What could have been asked for instead. Present on a filter, sort or group-by the API does not serve, so a correction is one edit rather than a round trip to read the schema.
        options:
          type: array
          items:
            type: string
          description: The values an enum accepts, on a value it does not.
        currentVersion:
          type: integer
          description: What the record's version actually is, on `stale_version`. With the value you sent it is everything needed to decide whether to re-read and retry or to stop.
        expectedVersion:
          type: integer
          description: The version you sent, echoed back on `stale_version`.
        requiredScope:
          type: string
          description: 'The capability the credential lacks. Empty nowhere: a route no credential can reach is human-only and says so in its scopes instead.'
    Error:
      type: object
      required:
      - code
      - message
      - recoveryHint
      - requestId
      properties:
        code:
          type: string
          enum:
          - unauthorized
          - forbidden_scope
          - standing_override_refused
          - workspace_not_found
          - validation_error
          - record_not_found
          - ambiguous_identity
          - duplicate_identity
          - stale_version
          - invalid_stage_transition
          - idempotency_conflict
          - not_reversible
          - merge_conflict
          - rate_limited
          - quota_exceeded
          - payload_too_large
          - workspace_capacity
          - payment_required
          - billing_state_stale
          - operation_in_flight
          - internal_error
        message:
          type: string
        recoveryHint:
          type: string
        requestId:
          type: string
        detail:
          $ref: '#/components/schemas/ErrorDetail'
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: An Indraft API token, or a WorkOS-issued session or MCP access token.
x-refined-from:
- indraft-io-openapi.json
- indraft-io.json