Update a webhook subscription
Change one subscription.
Change one subscription. Only the fields you send are touched.
Three behaviours to know before you use it:
headersREPLACES the whole map. Send the complete set you want, or{}to clear it. There is no per-header patch, because the stored values are encrypted and cannot be read back to merge against.secret: send a new value to rotate it, or an empty string to remove it and fall back to the organisation signing secret. It is never returned.- Changing
callback_urlissues a newsubscription_id. The URL is part of the storage key that keeps you from being subscribed twice to the same endpoint, so a new URL is a new row; the old one is removed for you. Always read thesubscription_idout of the response rather than assuming it survived.
Pausing is the reversible half of deleting: enabled: false keeps the URL,
headers, secret and event list, and stops every delivery until you set it
back. A pause is applied directly and never rewrites anything else.
Any other change re-writes the stored document. If the stored secret or a
stored header value can no longer be decrypted (secret_unavailable), it
cannot be carried forward and must be re-supplied in the same request.
The API runs several processes, each with its own 60-second subscription cache. A change is live immediately for the process that served this request and within 60 seconds everywhere else.
Errors: 400, 401, 403, 404, 422 (nothing to update), 429, 503.
Rate limit: 1000 requests per minute per organization (bucket default). Exceeding it returns 429 with Retry-After; the X-RateLimit-* response headers report your remaining allowance on every call.
v2/webhooks/{subscription_id}Authorization
AuthorizationRequiredBearer <token>
Your Graine API key. Create one in the dashboard under Developers, or via POST /v2/api-keys. Send it as Authorization: Bearer <key>.
In: header
Request Body
application/jsonRequiredcallback_urlCallback Url | null
Changing this issues a NEW subscription_id: the callback URL is part of the storage key.
1Maximum length: 2048event_typesEvent Types | null
Valid event types: all_processing_completed, call_completed, call_corrected, call_ringing, call_started, client_analysis_completed, platform_analysis_completed, recording_completed. Omitting event_types, or sending an empty list, resolves to all_processing_completed — there is no value that means "every event".
method_typeMethod Type | null
POST or PUT.
headersHeaders | null
REPLACES the stored header map. Send {} to clear it.
secretSecret | null
Replaces the signing secret. Send an empty string to remove it.
enabledEnabled | null
Pause or resume this subscription.
Path Parameters
subscription_idRequiredSubscription Id
The subscription_id returned on create.
Query Parameters
organization_idOrganization Id
Must match the organisation the API key belongs to.
Response Body
200
The stored subscription after the change.
subscription_idRequiredSubscription Id
Stable id for this subscription.
organization_idRequiredOrganization Id
Always the organisation the API key belongs to.
agent_idAgent Id | null
The agent this subscription is scoped to, or null for the organisation-wide default.
scopeRequiredScope
'agent' when agent_id is set, 'organization' for the org-wide default. An agent that has ANY enabled subscription of its own uses only those; the org-wide default is a fallback, not a union.
event_typesRequiredEvent Types
Resolved event list — never null, never empty.
@minItems 0
@minItems 0
callback_urlRequiredCallback Url
The endpoint we POST to.
method_typeRequiredMethod Type
POST or PUT.
headersRequiredHeaders
Configured header names, values masked as '***'. Values are never returned.
header_namesRequiredHeader Names
The same header names as a sorted list, for clients that want it flat.
@minItems 0
@minItems 0
enabledRequiredEnabled
A disabled subscription receives nothing.
has_secretRequiredHas Secret
True when a signing secret is configured.
secretSecret | null
Masked preview ('***') when a secret is set, otherwise null.
secret_unavailableRequiredSecret Unavailable
True when the stored secret can no longer be decrypted. Deliveries go out UNSIGNED while this is true and your signature check will never pass — PATCH a fresh secret to fix it.
created_atCreated At | null
ISO-8601 UTC.
updated_atUpdated At | null
ISO-8601 UTC.
created_byCreated By | null
Who created it.
400
1000 — malformed input the schema could not reject: an unknown event type, a method other than POST/PUT, a reserved header name, or a callback_url pointing at a private, loopback or metadata address.
errorRequiredError
Stable integer code from the /v2 error table. Branch on this.
messageRequiredMessage
One human-readable sentence. Wording may change; the code will not.
401
1100 — missing, unknown or inactive API key. 1101 — a browser session token was presented instead of a gat_ key.
errorRequiredError
Stable integer code from the /v2 error table. Branch on this.
messageRequiredMessage
One human-readable sentence. Wording may change; the code will not.
403
1102 — the key is valid but lacks the scope this endpoint requires, or names another organisation. GET /v2/scopes reports which scopes the key holds.
errorRequiredError
Stable integer code from the /v2 error table. Branch on this.
messageRequiredMessage
One human-readable sentence. Wording may change; the code will not.
404
1200 — no such subscription or delivery in this organisation. Cross-tenant reads answer 404, never 403.
errorRequiredError
Stable integer code from the /v2 error table. Branch on this.
messageRequiredMessage
One human-readable sentence. Wording may change; the code will not.
422
1001 — the body or query failed validation; the message names the first offending field.
errorRequiredinteger
Stable integer code from the error table. Branch on this, not on the message.
messageRequiredstring
One human-readable sentence. Wording may change; the code will not.
429
1300 — per-organisation rate limit exceeded. Carries Retry-After.
errorRequiredError
Stable integer code from the /v2 error table. Branch on this.
messageRequiredMessage
One human-readable sentence. Wording may change; the code will not.
503
1501 — the webhook subscription store is unreachable.
errorRequiredError
Stable integer code from the /v2 error table. Branch on this.
messageRequiredMessage
One human-readable sentence. Wording may change; the code will not.
504
1502 — an upstream did not respond in time.
errorRequiredError
Stable integer code from the /v2 error table. Branch on this.
messageRequiredMessage
One human-readable sentence. Wording may change; the code will not.
The stored subscription after the change.

