Indraft Webhooks API
The webhooks API from Indraft — 4 operation(s) for webhooks.
The webhooks API from Indraft — 4 operation(s) for webhooks.
Every API here is available over the APIs.io API and to AI agents over MCP.
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
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.curl "https://apis.io/api/v1/apis/indraft-io:indraft-io-webhooks-api"
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.
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: 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