{"openapi":"3.1.2","info":{"title":"Exende API","version":"1.0.0","description":"Agent-native infrastructure API for temporary callback endpoints and asynchronous webhook workflows."},"servers":[{"url":"https://api.exende.dev","description":"Exende API"}],"tags":[{"name":"System","description":"System and API-description endpoints."},{"name":"Callbacks","description":"Create and manage temporary callbacks."},{"name":"Webhooks","description":"Public webhook receiver endpoints."}],"paths":{"/health":{"get":{"tags":["System"],"summary":"Health check","operationId":"getHealth","responses":{"200":{"description":"Service is healthy.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Health"}}}}}}},"/openapi.json":{"get":{"tags":["System"],"summary":"Get the OpenAPI document","operationId":"getOpenApiDocument","responses":{"200":{"description":"The current OpenAPI 3.1 document.","content":{"application/json":{"schema":{"type":"object","required":["openapi","info","paths"],"properties":{"openapi":{"type":"string","example":"3.1.2"},"info":{"type":"object"},"paths":{"type":"object"}},"additionalProperties":true}}}}}}},"/v1/callbacks":{"post":{"tags":["Callbacks"],"summary":"Create a temporary callback","description":"Creates a temporary webhook callback endpoint. This endpoint is protected by x402 and requires payment before the callback is created.","operationId":"createCallback","requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false}}}},"responses":{"201":{"description":"Callback created successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Callback"}}}},"402":{"description":"Payment required. Payment requirements are returned in the PAYMENT-REQUIRED response header.","headers":{"PAYMENT-REQUIRED":{"description":"Base64-encoded x402 payment requirements.","schema":{"type":"string"}}}},"500":{"description":"An unexpected server error occurred.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"summary":"Internal error","value":{"error":{"code":"INTERNAL_ERROR","message":"An unexpected error occurred.","request_id":"req_81731247-7585-44a8-8716-d9dda3e0ff61"}}}}}}}}}},"/v1/callbacks/{id}/events":{"get":{"tags":["Callbacks"],"summary":"Get callback events","operationId":"getCallbackEvents","security":[{"callbackToken":[]}],"parameters":[{"$ref":"#/components/parameters/CallbackId"}],"responses":{"200":{"description":"All stored events in deterministic receipt order.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CallbackEvents"}}}},"400":{"description":"The callback ID is malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INVALID_CALLBACK_ID":{"summary":"Invalid callback ID","value":{"error":{"code":"INVALID_CALLBACK_ID","message":"The callback ID format is invalid.","request_id":"req_81731247-7585-44a8-8716-d9dda3e0ff61"}}}}}}},"401":{"description":"Callback read-token authentication failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"MISSING_AUTHORIZATION":{"summary":"Authorization header missing","value":{"error":{"code":"MISSING_AUTHORIZATION","message":"Authorization header is required.","request_id":"req_81731247-7585-44a8-8716-d9dda3e0ff61"}}},"INVALID_AUTHORIZATION":{"summary":"Authorization scheme invalid","value":{"error":{"code":"INVALID_AUTHORIZATION","message":"Authorization must use the Bearer scheme.","request_id":"req_81731247-7585-44a8-8716-d9dda3e0ff61"}}},"INVALID_TOKEN":{"summary":"Read token invalid","value":{"error":{"code":"INVALID_TOKEN","message":"The read token is invalid.","request_id":"req_81731247-7585-44a8-8716-d9dda3e0ff61"}}}}}}},"404":{"description":"The callback does not exist.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"CALLBACK_NOT_FOUND":{"summary":"Callback not found","value":{"error":{"code":"CALLBACK_NOT_FOUND","message":"The callback does not exist.","request_id":"req_81731247-7585-44a8-8716-d9dda3e0ff61"}}}}}}},"410":{"description":"The callback has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"CALLBACK_EXPIRED":{"summary":"Callback expired","value":{"error":{"code":"CALLBACK_EXPIRED","message":"The callback has expired.","request_id":"req_81731247-7585-44a8-8716-d9dda3e0ff61"}}}}}}},"500":{"description":"An unexpected server error occurred.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"summary":"Internal error","value":{"error":{"code":"INTERNAL_ERROR","message":"An unexpected error occurred.","request_id":"req_81731247-7585-44a8-8716-d9dda3e0ff61"}}}}}}}}}},"/v1/callbacks/{id}/wait":{"get":{"tags":["Callbacks"],"summary":"Wait for the next callback event","description":"Waits for an event. Use after to wait only for events received after a previously returned event.","operationId":"waitForCallbackEvent","security":[{"callbackToken":[]}],"parameters":[{"$ref":"#/components/parameters/CallbackId"},{"name":"timeout","in":"query","required":false,"description":"Coerced with JavaScript Number. Missing or non-finite values default to 30. Finite values are floored, then clamped to 1-30 seconds. Examples: 1.9 -> 1, 0 -> 1, 31 -> 30, invalid -> 30.","schema":{"anyOf":[{"type":"number"},{"type":"string"}],"default":30,"examples":[30,1.9,0,31,"invalid"]}},{"name":"after","in":"query","required":false,"description":"Event ID after which Exende should wait for the next event.","schema":{"type":"string","pattern":"^evt_[a-f0-9]{32}$","example":"evt_f944b3e97ef8d15fd99bd1fe65fd42ee"}}],"responses":{"200":{"description":"An event was received or the normalized wait interval elapsed.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/WaitEventResponse"},{"$ref":"#/components/schemas/WaitTimeoutResponse"}]}}}},"400":{"description":"The callback ID is malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INVALID_CALLBACK_ID":{"summary":"Invalid callback ID","value":{"error":{"code":"INVALID_CALLBACK_ID","message":"The callback ID format is invalid.","request_id":"req_81731247-7585-44a8-8716-d9dda3e0ff61"}}}}}}},"401":{"description":"Callback read-token authentication failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"MISSING_AUTHORIZATION":{"summary":"Authorization header missing","value":{"error":{"code":"MISSING_AUTHORIZATION","message":"Authorization header is required.","request_id":"req_81731247-7585-44a8-8716-d9dda3e0ff61"}}},"INVALID_AUTHORIZATION":{"summary":"Authorization scheme invalid","value":{"error":{"code":"INVALID_AUTHORIZATION","message":"Authorization must use the Bearer scheme.","request_id":"req_81731247-7585-44a8-8716-d9dda3e0ff61"}}},"INVALID_TOKEN":{"summary":"Read token invalid","value":{"error":{"code":"INVALID_TOKEN","message":"The read token is invalid.","request_id":"req_81731247-7585-44a8-8716-d9dda3e0ff61"}}}}}}},"404":{"description":"The callback or the event referenced by after does not exist.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"CALLBACK_NOT_FOUND":{"summary":"Callback not found","value":{"error":{"code":"CALLBACK_NOT_FOUND","message":"The callback does not exist.","request_id":"req_81731247-7585-44a8-8716-d9dda3e0ff61"}}},"EVENT_NOT_FOUND":{"summary":"After event not found","value":{"error":{"code":"EVENT_NOT_FOUND","message":"The event specified in \"after\" does not exist.","request_id":"req_81731247-7585-44a8-8716-d9dda3e0ff61"}}}}}}},"410":{"description":"The callback has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"CALLBACK_EXPIRED":{"summary":"Callback expired","value":{"error":{"code":"CALLBACK_EXPIRED","message":"The callback has expired.","request_id":"req_81731247-7585-44a8-8716-d9dda3e0ff61"}}}}}}},"500":{"description":"An unexpected server error occurred.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"summary":"Internal error","value":{"error":{"code":"INTERNAL_ERROR","message":"An unexpected error occurred.","request_id":"req_81731247-7585-44a8-8716-d9dda3e0ff61"}}}}}}}}}},"/v1/callbacks/{id}":{"delete":{"tags":["Callbacks"],"summary":"Delete a callback","operationId":"deleteCallback","security":[{"callbackToken":[]}],"parameters":[{"$ref":"#/components/parameters/CallbackId"}],"responses":{"200":{"description":"Callback deleted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteCallbackResponse"}}}},"400":{"description":"The callback ID is malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INVALID_CALLBACK_ID":{"summary":"Invalid callback ID","value":{"error":{"code":"INVALID_CALLBACK_ID","message":"The callback ID format is invalid.","request_id":"req_81731247-7585-44a8-8716-d9dda3e0ff61"}}}}}}},"401":{"description":"Callback read-token authentication failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"MISSING_AUTHORIZATION":{"summary":"Authorization header missing","value":{"error":{"code":"MISSING_AUTHORIZATION","message":"Authorization header is required.","request_id":"req_81731247-7585-44a8-8716-d9dda3e0ff61"}}},"INVALID_AUTHORIZATION":{"summary":"Authorization scheme invalid","value":{"error":{"code":"INVALID_AUTHORIZATION","message":"Authorization must use the Bearer scheme.","request_id":"req_81731247-7585-44a8-8716-d9dda3e0ff61"}}},"INVALID_TOKEN":{"summary":"Read token invalid","value":{"error":{"code":"INVALID_TOKEN","message":"The read token is invalid.","request_id":"req_81731247-7585-44a8-8716-d9dda3e0ff61"}}}}}}},"404":{"description":"The callback does not exist.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"CALLBACK_NOT_FOUND":{"summary":"Callback not found","value":{"error":{"code":"CALLBACK_NOT_FOUND","message":"The callback does not exist.","request_id":"req_81731247-7585-44a8-8716-d9dda3e0ff61"}}}}}}},"410":{"description":"The callback has expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"CALLBACK_EXPIRED":{"summary":"Callback expired","value":{"error":{"code":"CALLBACK_EXPIRED","message":"The callback has expired.","request_id":"req_81731247-7585-44a8-8716-d9dda3e0ff61"}}}}}}},"500":{"description":"An unexpected server error occurred.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"summary":"Internal error","value":{"error":{"code":"INTERNAL_ERROR","message":"An unexpected error occurred.","request_id":"req_81731247-7585-44a8-8716-d9dda3e0ff61"}}}}}}}}}},"/hooks/{id}":{"servers":[{"url":"https://cb.exende.dev","description":"Exende callback receiver"}],"post":{"tags":["Webhooks"],"summary":"Send webhook event","operationId":"sendWebhook","parameters":[{"$ref":"#/components/parameters/CallbackId"}],"requestBody":{"required":false,"description":"The raw webhook payload. Omit Content-Type to store the body as text.","content":{"application/json":{"schema":{"description":"Any valid JSON value."}},"text/*":{"schema":{"type":"string"}},"application/x-www-form-urlencoded":{"schema":{"type":"string","description":"The original URL-encoded body, stored without decoding."}}}},"responses":{"200":{"description":"Webhook event stored.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookAccepted"}}}},"400":{"description":"The callback ID or JSON body is invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INVALID_CALLBACK_ID":{"summary":"Invalid callback ID","value":{"error":{"code":"INVALID_CALLBACK_ID","message":"The callback ID format is invalid.","request_id":"req_81731247-7585-44a8-8716-d9dda3e0ff61"}}},"INVALID_JSON":{"summary":"Malformed JSON body","value":{"error":{"code":"INVALID_JSON","message":"The webhook body contains invalid JSON.","request_id":"req_81731247-7585-44a8-8716-d9dda3e0ff61"}}}}}}},"404":{"description":"The callback does not exist.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"CALLBACK_NOT_FOUND":{"summary":"Callback not found","value":{"error":{"code":"CALLBACK_NOT_FOUND","message":"The callback does not exist.","request_id":"req_81731247-7585-44a8-8716-d9dda3e0ff61"}}}}}}},"410":{"description":"The callback expired or has reached its event limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"CALLBACK_EXPIRED":{"summary":"Callback expired","value":{"error":{"code":"CALLBACK_EXPIRED","message":"The callback has expired.","request_id":"req_81731247-7585-44a8-8716-d9dda3e0ff61"}}},"CALLBACK_EVENT_LIMIT_REACHED":{"summary":"Event limit reached","value":{"error":{"code":"CALLBACK_EVENT_LIMIT_REACHED","message":"The callback reached its event limit.","request_id":"req_81731247-7585-44a8-8716-d9dda3e0ff61"}}}}}}},"413":{"description":"The callback payload limit was exceeded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"PAYLOAD_TOO_LARGE":{"summary":"Payload too large","value":{"error":{"code":"PAYLOAD_TOO_LARGE","message":"The webhook payload is too large.","request_id":"req_81731247-7585-44a8-8716-d9dda3e0ff61"}}}}}}},"415":{"description":"The media type is unsupported.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNSUPPORTED_MEDIA_TYPE":{"summary":"Unsupported media type","value":{"error":{"code":"UNSUPPORTED_MEDIA_TYPE","message":"This webhook content type is not supported.","request_id":"req_81731247-7585-44a8-8716-d9dda3e0ff61"}}}}}}},"429":{"description":"The per-callback rate limit was exceeded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"RATE_LIMIT_EXCEEDED":{"summary":"Rate limit exceeded","value":{"error":{"code":"RATE_LIMIT_EXCEEDED","message":"Too many requests for this callback.","request_id":"req_81731247-7585-44a8-8716-d9dda3e0ff61"}}}}}}},"500":{"description":"An unexpected server error occurred.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"summary":"Internal error","value":{"error":{"code":"INTERNAL_ERROR","message":"An unexpected error occurred.","request_id":"req_81731247-7585-44a8-8716-d9dda3e0ff61"}}}}}}}}},"put":{"tags":["Webhooks"],"summary":"Send webhook event using PUT","operationId":"sendWebhookPut","parameters":[{"$ref":"#/components/parameters/CallbackId"}],"requestBody":{"required":false,"description":"The raw webhook payload. Omit Content-Type to store the body as text.","content":{"application/json":{"schema":{"description":"Any valid JSON value."}},"text/*":{"schema":{"type":"string"}},"application/x-www-form-urlencoded":{"schema":{"type":"string","description":"The original URL-encoded body, stored without decoding."}}}},"responses":{"200":{"description":"Webhook event stored.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookAccepted"}}}},"400":{"description":"The callback ID or JSON body is invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INVALID_CALLBACK_ID":{"summary":"Invalid callback ID","value":{"error":{"code":"INVALID_CALLBACK_ID","message":"The callback ID format is invalid.","request_id":"req_81731247-7585-44a8-8716-d9dda3e0ff61"}}},"INVALID_JSON":{"summary":"Malformed JSON body","value":{"error":{"code":"INVALID_JSON","message":"The webhook body contains invalid JSON.","request_id":"req_81731247-7585-44a8-8716-d9dda3e0ff61"}}}}}}},"404":{"description":"The callback does not exist.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"CALLBACK_NOT_FOUND":{"summary":"Callback not found","value":{"error":{"code":"CALLBACK_NOT_FOUND","message":"The callback does not exist.","request_id":"req_81731247-7585-44a8-8716-d9dda3e0ff61"}}}}}}},"410":{"description":"The callback expired or has reached its event limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"CALLBACK_EXPIRED":{"summary":"Callback expired","value":{"error":{"code":"CALLBACK_EXPIRED","message":"The callback has expired.","request_id":"req_81731247-7585-44a8-8716-d9dda3e0ff61"}}},"CALLBACK_EVENT_LIMIT_REACHED":{"summary":"Event limit reached","value":{"error":{"code":"CALLBACK_EVENT_LIMIT_REACHED","message":"The callback reached its event limit.","request_id":"req_81731247-7585-44a8-8716-d9dda3e0ff61"}}}}}}},"413":{"description":"The callback payload limit was exceeded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"PAYLOAD_TOO_LARGE":{"summary":"Payload too large","value":{"error":{"code":"PAYLOAD_TOO_LARGE","message":"The webhook payload is too large.","request_id":"req_81731247-7585-44a8-8716-d9dda3e0ff61"}}}}}}},"415":{"description":"The media type is unsupported.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNSUPPORTED_MEDIA_TYPE":{"summary":"Unsupported media type","value":{"error":{"code":"UNSUPPORTED_MEDIA_TYPE","message":"This webhook content type is not supported.","request_id":"req_81731247-7585-44a8-8716-d9dda3e0ff61"}}}}}}},"429":{"description":"The per-callback rate limit was exceeded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"RATE_LIMIT_EXCEEDED":{"summary":"Rate limit exceeded","value":{"error":{"code":"RATE_LIMIT_EXCEEDED","message":"Too many requests for this callback.","request_id":"req_81731247-7585-44a8-8716-d9dda3e0ff61"}}}}}}},"500":{"description":"An unexpected server error occurred.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"summary":"Internal error","value":{"error":{"code":"INTERNAL_ERROR","message":"An unexpected error occurred.","request_id":"req_81731247-7585-44a8-8716-d9dda3e0ff61"}}}}}}}}},"patch":{"tags":["Webhooks"],"summary":"Send webhook event using PATCH","operationId":"sendWebhookPatch","parameters":[{"$ref":"#/components/parameters/CallbackId"}],"requestBody":{"required":false,"description":"The raw webhook payload. Omit Content-Type to store the body as text.","content":{"application/json":{"schema":{"description":"Any valid JSON value."}},"text/*":{"schema":{"type":"string"}},"application/x-www-form-urlencoded":{"schema":{"type":"string","description":"The original URL-encoded body, stored without decoding."}}}},"responses":{"200":{"description":"Webhook event stored.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookAccepted"}}}},"400":{"description":"The callback ID or JSON body is invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INVALID_CALLBACK_ID":{"summary":"Invalid callback ID","value":{"error":{"code":"INVALID_CALLBACK_ID","message":"The callback ID format is invalid.","request_id":"req_81731247-7585-44a8-8716-d9dda3e0ff61"}}},"INVALID_JSON":{"summary":"Malformed JSON body","value":{"error":{"code":"INVALID_JSON","message":"The webhook body contains invalid JSON.","request_id":"req_81731247-7585-44a8-8716-d9dda3e0ff61"}}}}}}},"404":{"description":"The callback does not exist.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"CALLBACK_NOT_FOUND":{"summary":"Callback not found","value":{"error":{"code":"CALLBACK_NOT_FOUND","message":"The callback does not exist.","request_id":"req_81731247-7585-44a8-8716-d9dda3e0ff61"}}}}}}},"410":{"description":"The callback expired or has reached its event limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"CALLBACK_EXPIRED":{"summary":"Callback expired","value":{"error":{"code":"CALLBACK_EXPIRED","message":"The callback has expired.","request_id":"req_81731247-7585-44a8-8716-d9dda3e0ff61"}}},"CALLBACK_EVENT_LIMIT_REACHED":{"summary":"Event limit reached","value":{"error":{"code":"CALLBACK_EVENT_LIMIT_REACHED","message":"The callback reached its event limit.","request_id":"req_81731247-7585-44a8-8716-d9dda3e0ff61"}}}}}}},"413":{"description":"The callback payload limit was exceeded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"PAYLOAD_TOO_LARGE":{"summary":"Payload too large","value":{"error":{"code":"PAYLOAD_TOO_LARGE","message":"The webhook payload is too large.","request_id":"req_81731247-7585-44a8-8716-d9dda3e0ff61"}}}}}}},"415":{"description":"The media type is unsupported.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNSUPPORTED_MEDIA_TYPE":{"summary":"Unsupported media type","value":{"error":{"code":"UNSUPPORTED_MEDIA_TYPE","message":"This webhook content type is not supported.","request_id":"req_81731247-7585-44a8-8716-d9dda3e0ff61"}}}}}}},"429":{"description":"The per-callback rate limit was exceeded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"RATE_LIMIT_EXCEEDED":{"summary":"Rate limit exceeded","value":{"error":{"code":"RATE_LIMIT_EXCEEDED","message":"Too many requests for this callback.","request_id":"req_81731247-7585-44a8-8716-d9dda3e0ff61"}}}}}}},"500":{"description":"An unexpected server error occurred.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"summary":"Internal error","value":{"error":{"code":"INTERNAL_ERROR","message":"An unexpected error occurred.","request_id":"req_81731247-7585-44a8-8716-d9dda3e0ff61"}}}}}}}}}}},"components":{"securitySchemes":{"callbackToken":{"type":"http","scheme":"bearer","bearerFormat":"Exende callback read token","description":"Private read token returned once when the callback is created."}},"parameters":{"CallbackId":{"name":"id","in":"path","required":true,"description":"Callback identifier.","schema":{"type":"string","pattern":"^cb_[A-Za-z0-9]{24}$","example":"cb_3t2cC09baD4yOvoeVMDK2vGQ"}}},"schemas":{"Health":{"type":"object","additionalProperties":false,"required":["status","service","version"],"properties":{"status":{"type":"string","const":"ok"},"service":{"type":"string","const":"exende-api"},"version":{"type":"string","const":"1.0.0"}}},"Callback":{"type":"object","additionalProperties":false,"required":["id","callback_url","events_url","wait_url","read_token","expires_at","limits"],"properties":{"id":{"type":"string","pattern":"^cb_[A-Za-z0-9]{24}$","example":"cb_3t2cC09baD4yOvoeVMDK2vGQ"},"callback_url":{"type":"string","format":"uri","example":"https://cb.exende.dev/hooks/cb_3t2cC09baD4yOvoeVMDK2vGQ"},"events_url":{"type":"string","format":"uri"},"wait_url":{"type":"string","format":"uri"},"read_token":{"type":"string","example":"ex_cb_sk_..."},"expires_at":{"type":"string","format":"date-time"},"limits":{"type":"object","additionalProperties":false,"required":["events","payload_bytes"],"properties":{"events":{"type":"integer","example":10},"payload_bytes":{"type":"integer","example":262144}}}}},"Event":{"type":"object","additionalProperties":false,"required":["id","received_at","method","content_type","headers","body","size_bytes"],"properties":{"id":{"type":"string","pattern":"^evt_[a-f0-9]{32}$","example":"evt_f944b3e97ef8d15fd99bd1fe65fd42ee"},"received_at":{"type":"string","format":"date-time"},"method":{"type":"string","enum":["POST","PUT","PATCH"]},"content_type":{"type":["string","null"]},"headers":{"type":"object","additionalProperties":{"type":"string"}},"body":{"description":"Parsed JSON for JSON events; otherwise the original string."},"size_bytes":{"type":["integer","null"],"minimum":0}}},"CallbackEvents":{"type":"object","additionalProperties":false,"required":["callback_id","status","expires_at","event_count","events"],"properties":{"callback_id":{"type":"string","pattern":"^cb_[A-Za-z0-9]{24}$"},"status":{"type":"string"},"expires_at":{"type":"string","format":"date-time"},"event_count":{"type":"integer","minimum":0},"events":{"type":"array","items":{"$ref":"#/components/schemas/Event"}}}},"WaitEventResponse":{"type":"object","additionalProperties":false,"required":["received","timeout","event","next_wait_url"],"properties":{"received":{"type":"boolean","const":true},"timeout":{"type":"boolean","const":false},"event":{"$ref":"#/components/schemas/Event"},"next_wait_url":{"type":"string","format":"uri-reference","example":"/v1/callbacks/cb_3t2cC09baD4yOvoeVMDK2vGQ/wait?after=evt_f944b3e97ef8d15fd99bd1fe65fd42ee&timeout=30"}}},"WaitTimeoutResponse":{"type":"object","additionalProperties":false,"required":["received","timeout","after"],"properties":{"received":{"type":"boolean","const":false},"timeout":{"type":"boolean","const":true},"after":{"type":["string","null"],"pattern":"^evt_[a-f0-9]{32}$"}}},"DeleteCallbackResponse":{"type":"object","additionalProperties":false,"required":["deleted","callback_id"],"properties":{"deleted":{"type":"boolean","const":true},"callback_id":{"type":"string","pattern":"^cb_[A-Za-z0-9]{24}$"}}},"WebhookAccepted":{"type":"object","additionalProperties":false,"required":["received","event_id"],"properties":{"received":{"type":"boolean","const":true},"event_id":{"type":"string","pattern":"^evt_[a-f0-9]{32}$","example":"evt_f944b3e97ef8d15fd99bd1fe65fd42ee"}}},"ErrorResponse":{"type":"object","additionalProperties":false,"required":["error"],"properties":{"error":{"type":"object","additionalProperties":false,"required":["code","message","request_id"],"properties":{"code":{"type":"string"},"message":{"type":"string"},"request_id":{"type":"string","example":"req_81731247-7585-44a8-8716-d9dda3e0ff61"}}}}}}}}