{"openapi":"3.1.1","info":{"title":"WingsFlow Public API","version":"1.0.0","description":"Locked P0 contract. Isolated staging is deployed; production and authenticated provider qualification remain separate gates."},"servers":[{"url":"https://alq4gr135m2h40f7fpmw5e9n.77.37.45.251.sslip.io/v1","description":"Isolated staging; authenticated client/provider qualification pending"},{"url":"https://api.wingsflow.example/v1","description":"Undeployed production placeholder"}],"security":[{"ApiKey":[]}],"paths":{"/me":{"get":{"operationId":"getIdentity","summary":"get identity","description":"P0. Any valid API key. Read is tenant and grant scoped.","tags":["Public v1"],"security":[{"ApiKey":[]}],"x-required-scopes":[],"parameters":[],"responses":{"200":{"description":"Success.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Identity"},"request_id":{"type":"string","maxLength":180}},"required":["data","request_id"]},"example":{"data":{"tenant_id":"11111111-1111-4111-8111-111111111111","integration_id":"11111111-1111-4111-8111-111111111111","environment":"test","scopes":[],"allowed_channel_ids":[],"allowed_template_ids":[],"capabilities":[]},"request_id":"example"}}}},"400":{"description":"Structured 400 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"401":{"description":"Structured 401 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_api_key","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"403":{"description":"Structured 403 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"404":{"description":"Structured 404 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"429":{"description":"Structured 429 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":true}}}}},"500":{"description":"Structured 500 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"503":{"description":"Structured 503 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":true}}}}}}}},"/channels":{"get":{"operationId":"listChannels","summary":"list channels","description":"P0. Requires channels:read. Read is tenant and grant scoped.","tags":["Public v1"],"security":[{"ApiKey":[]}],"x-required-scopes":["channels:read"],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},{"name":"cursor","in":"query","required":false,"schema":{"type":"string","maxLength":2000}}],"responses":{"200":{"description":"Success.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Channel"}},"pagination":{"type":"object","additionalProperties":false,"properties":{"next_cursor":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}]},"has_more":{"type":"boolean"}},"required":["next_cursor","has_more"]},"request_id":{"type":"string","maxLength":180}},"required":["data","pagination","request_id"]},"example":{"data":[],"pagination":{"next_cursor":"example","has_more":false},"request_id":"example"}}}},"400":{"description":"Structured 400 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"401":{"description":"Structured 401 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_api_key","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"403":{"description":"Structured 403 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"404":{"description":"Structured 404 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"429":{"description":"Structured 429 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":true}}}}},"500":{"description":"Structured 500 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"503":{"description":"Structured 503 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":true}}}}}}}},"/contact-identities/{external_id}":{"put":{"operationId":"upsertExternalContact","summary":"upsert external contact","description":"P0. Requires contacts:write. Every mutation requires Idempotency-Key; seven-day response retention, current authorization rechecked.","tags":["Public v1"],"security":[{"ApiKey":[]}],"x-required-scopes":["contacts:write"],"parameters":[{"name":"external_id","in":"path","required":true,"schema":{"type":"string","maxLength":180,"minLength":1}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":8,"maxLength":128,"pattern":"^[ -~]+$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContactWrite"},"example":{"phone":"+919876543210"}}}},"responses":{"200":{"description":"Created.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Contact"},"request_id":{"type":"string","maxLength":180}},"required":["data","request_id"]},"example":{"data":{"id":"11111111-1111-4111-8111-111111111111","external_id":"example","phone":"+919876543210","name":"example","version":1,"suppressed":false,"tags":[],"consents":{"service":{"action":"opt_in","occurred_at":"2026-09-14T06:30:00Z"},"marketing":{"action":"opt_in","occurred_at":"2026-09-14T06:30:00Z"}}},"request_id":"example"}}}},"201":{"description":"Created.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Contact"},"request_id":{"type":"string","maxLength":180}},"required":["data","request_id"]},"example":{"data":{"id":"11111111-1111-4111-8111-111111111111","external_id":"example","phone":"+919876543210","name":"example","version":1,"suppressed":false,"tags":[],"consents":{"service":{"action":"opt_in","occurred_at":"2026-09-14T06:30:00Z"},"marketing":{"action":"opt_in","occurred_at":"2026-09-14T06:30:00Z"}}},"request_id":"example"}}}},"400":{"description":"Structured 400 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"401":{"description":"Structured 401 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_api_key","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"403":{"description":"Structured 403 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"404":{"description":"Structured 404 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"409":{"description":"Structured 409 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"413":{"description":"Structured 413 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"415":{"description":"Structured 415 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"422":{"description":"Structured 422 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"429":{"description":"Structured 429 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":true}}}}},"500":{"description":"Structured 500 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"503":{"description":"Structured 503 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":true}}}}}}}},"/contacts/{contact_id}":{"get":{"operationId":"getContact","summary":"get contact","description":"P0. Requires contacts:read. Read is tenant and grant scoped.","tags":["Public v1"],"security":[{"ApiKey":[]}],"x-required-scopes":["contacts:read"],"parameters":[{"name":"contact_id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Contact"},"request_id":{"type":"string","maxLength":180}},"required":["data","request_id"]},"example":{"data":{"id":"11111111-1111-4111-8111-111111111111","external_id":"example","phone":"+919876543210","name":"example","version":1,"suppressed":false,"tags":[],"consents":{"service":{"action":"opt_in","occurred_at":"2026-09-14T06:30:00Z"},"marketing":{"action":"opt_in","occurred_at":"2026-09-14T06:30:00Z"}}},"request_id":"example"}}}},"400":{"description":"Structured 400 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"401":{"description":"Structured 401 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_api_key","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"403":{"description":"Structured 403 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"404":{"description":"Structured 404 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"429":{"description":"Structured 429 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":true}}}}},"500":{"description":"Structured 500 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"503":{"description":"Structured 503 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":true}}}}}}}},"/contacts/{contact_id}/consents":{"post":{"operationId":"recordConsent","summary":"record consent","description":"P0. Requires consents:write. Every mutation requires Idempotency-Key; seven-day response retention, current authorization rechecked.","tags":["Public v1"],"security":[{"ApiKey":[]}],"x-required-scopes":["consents:write"],"parameters":[{"name":"contact_id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":8,"maxLength":128,"pattern":"^[ -~]+$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Consent"},"example":{"purpose":"service","action":"opt_in","source":"example","evidence_reference":"example","occurred_at":"2026-09-14T06:30:00Z"}}}},"responses":{"201":{"description":"Created.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/ConsentReceipt"},"request_id":{"type":"string","maxLength":180}},"required":["data","request_id"]},"example":{"data":{"id":"11111111-1111-4111-8111-111111111111","contact_id":"11111111-1111-4111-8111-111111111111","received_at":"2026-09-14T06:30:00Z","effective_action":"opt_in","effective_at":"2026-09-14T06:30:00Z","applied":false},"request_id":"example"}}}},"400":{"description":"Structured 400 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"401":{"description":"Structured 401 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_api_key","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"403":{"description":"Structured 403 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"404":{"description":"Structured 404 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"409":{"description":"Structured 409 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"413":{"description":"Structured 413 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"415":{"description":"Structured 415 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"422":{"description":"Structured 422 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"429":{"description":"Structured 429 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":true}}}}},"500":{"description":"Structured 500 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"503":{"description":"Structured 503 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":true}}}}}}}},"/templates":{"get":{"operationId":"listTemplates","summary":"list templates","description":"P0. Requires templates:read. Read is tenant and grant scoped.","tags":["Public v1"],"security":[{"ApiKey":[]}],"x-required-scopes":["templates:read"],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},{"name":"cursor","in":"query","required":false,"schema":{"type":"string","maxLength":2000}},{"name":"channel_id","in":"query","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/TemplateResource"}},"pagination":{"type":"object","additionalProperties":false,"properties":{"next_cursor":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}]},"has_more":{"type":"boolean"}},"required":["next_cursor","has_more"]},"request_id":{"type":"string","maxLength":180}},"required":["data","pagination","request_id"]},"example":{"data":[],"pagination":{"next_cursor":"example","has_more":false},"request_id":"example"}}}},"400":{"description":"Structured 400 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"401":{"description":"Structured 401 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_api_key","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"403":{"description":"Structured 403 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"404":{"description":"Structured 404 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"429":{"description":"Structured 429 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":true}}}}},"500":{"description":"Structured 500 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"503":{"description":"Structured 503 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":true}}}}}}}},"/templates/{template_id}":{"get":{"operationId":"getTemplate","summary":"get template","description":"P0. Requires templates:read. Read is tenant and grant scoped.","tags":["Public v1"],"security":[{"ApiKey":[]}],"x-required-scopes":["templates:read"],"parameters":[{"name":"template_id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"channel_id","in":"query","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"version","in":"query","required":true,"schema":{"type":"integer","minimum":1}}],"responses":{"200":{"description":"Success.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/TemplateResource"},"request_id":{"type":"string","maxLength":180}},"required":["data","request_id"]},"example":{"data":{"id":"11111111-1111-4111-8111-111111111111","version":1,"channel_id":"11111111-1111-4111-8111-111111111111","name":"example","language":"example","purpose":"service","status":"approved","parameters":[],"updated_at":"2026-09-14T06:30:00Z"},"request_id":"example"}}}},"400":{"description":"Structured 400 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"401":{"description":"Structured 401 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_api_key","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"403":{"description":"Structured 403 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"404":{"description":"Structured 404 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"429":{"description":"Structured 429 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":true}}}}},"500":{"description":"Structured 500 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"503":{"description":"Structured 503 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":true}}}}}}}},"/messages":{"post":{"operationId":"queueMessage","summary":"queue message","description":"P0. Requires messages:write. Every mutation requires Idempotency-Key; seven-day response retention, current authorization rechecked.","tags":["Public v1"],"security":[{"ApiKey":[]}],"x-required-scopes":["messages:write"],"parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":8,"maxLength":128,"pattern":"^[ -~]+$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageWrite"},"example":{"channel_id":"11111111-1111-4111-8111-111111111111","contact_id":"11111111-1111-4111-8111-111111111111","client_reference":"example","message":{"type":"text","conversation_id":"11111111-1111-4111-8111-111111111111","text":"example"}}}}},"responses":{"202":{"description":"Durably admitted, not delivered.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Message"},"request_id":{"type":"string","maxLength":180}},"required":["data","request_id"]},"example":{"data":{"id":"11111111-1111-4111-8111-111111111111","status":"queued","version":1,"client_reference":"example","channel_id":"11111111-1111-4111-8111-111111111111","contact_id":"11111111-1111-4111-8111-111111111111","conversation_id":"11111111-1111-4111-8111-111111111111","correlation_id":"example","error":{"code":"example","message":"example","retryable":false}},"request_id":"example"}}}},"400":{"description":"Structured 400 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"401":{"description":"Structured 401 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_api_key","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"403":{"description":"Structured 403 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"404":{"description":"Structured 404 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"409":{"description":"Structured 409 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"413":{"description":"Structured 413 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"415":{"description":"Structured 415 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"422":{"description":"Structured 422 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"429":{"description":"Structured 429 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":true}}}}},"500":{"description":"Structured 500 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"503":{"description":"Structured 503 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":true}}}}}}}},"/messages/{message_id}":{"get":{"operationId":"getMessage","summary":"get message","description":"P0. Requires messages:read. Read is tenant and grant scoped.","tags":["Public v1"],"security":[{"ApiKey":[]}],"x-required-scopes":["messages:read"],"parameters":[{"name":"message_id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Message"},"request_id":{"type":"string","maxLength":180}},"required":["data","request_id"]},"example":{"data":{"id":"11111111-1111-4111-8111-111111111111","status":"queued","version":1,"client_reference":"example","channel_id":"11111111-1111-4111-8111-111111111111","contact_id":"11111111-1111-4111-8111-111111111111","conversation_id":"11111111-1111-4111-8111-111111111111","correlation_id":"example","error":{"code":"example","message":"example","retryable":false}},"request_id":"example"}}}},"400":{"description":"Structured 400 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"401":{"description":"Structured 401 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_api_key","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"403":{"description":"Structured 403 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"404":{"description":"Structured 404 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"429":{"description":"Structured 429 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":true}}}}},"500":{"description":"Structured 500 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"503":{"description":"Structured 503 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":true}}}}}}}},"/events":{"post":{"operationId":"ingestEvent","summary":"ingest event","description":"P0. Requires events:write. Every mutation requires Idempotency-Key; seven-day response retention, current authorization rechecked. Inline customer additionally requires contacts:write. Event receipt does not imply a matching action or WhatsApp delivery.","tags":["Public v1"],"security":[{"ApiKey":[]}],"x-required-scopes":["events:write"],"parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":8,"maxLength":128,"pattern":"^[ -~]+$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EventWrite"},"example":{"source_event_id":"storefront:order:ORD-123:created:v1","event":"order.created","schema_version":"1","occurred_at":"2026-09-14T06:30:00Z","contact_id":"11111111-1111-4111-8111-111111111111","data":{"order_id":"ORD-123","aggregate_version":1,"amount_minor":2500000,"currency":"INR"},"correlation_id":"order:ORD-123"}}}},"responses":{"202":{"description":"Durably admitted, not delivered.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Event"},"request_id":{"type":"string","maxLength":180}},"required":["data","request_id"]},"example":{"data":{"id":"11111111-1111-4111-8111-111111111111","status":"received","message_ids":[],"outcome":{"binding_id":"11111111-1111-4111-8111-111111111111","binding_version":1,"reason_code":"example"},"error":{"code":"example","message":"example","retryable":false}},"request_id":"example"}}}},"400":{"description":"Structured 400 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"401":{"description":"Structured 401 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_api_key","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"403":{"description":"Structured 403 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"404":{"description":"Structured 404 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"409":{"description":"Structured 409 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"413":{"description":"Structured 413 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"415":{"description":"Structured 415 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"422":{"description":"Structured 422 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"429":{"description":"Structured 429 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":true}}}}},"500":{"description":"Structured 500 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"503":{"description":"Structured 503 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":true}}}}}}}},"/events/{event_id}":{"get":{"operationId":"getEvent","summary":"get event","description":"P0. Requires events:read. Read is tenant and grant scoped.","tags":["Public v1"],"security":[{"ApiKey":[]}],"x-required-scopes":["events:read"],"parameters":[{"name":"event_id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Success.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Event"},"request_id":{"type":"string","maxLength":180}},"required":["data","request_id"]},"example":{"data":{"id":"11111111-1111-4111-8111-111111111111","status":"received","message_ids":[],"outcome":{"binding_id":"11111111-1111-4111-8111-111111111111","binding_version":1,"reason_code":"example"},"error":{"code":"example","message":"example","retryable":false}},"request_id":"example"}}}},"400":{"description":"Structured 400 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"401":{"description":"Structured 401 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_api_key","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"403":{"description":"Structured 403 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"404":{"description":"Structured 404 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"429":{"description":"Structured 429 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":true}}}}},"500":{"description":"Structured 500 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"503":{"description":"Structured 503 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":true}}}}}}}},"/webhook-subscriptions":{"get":{"operationId":"listSubscriptions","summary":"list subscriptions","description":"P0. Requires webhooks:read. Read is tenant and grant scoped. Subscription event scopes and grants are rechecked. Signing secrets use protected one-hour encrypted response recovery; later replay returns secret_response_expired.","tags":["Public v1"],"security":[{"ApiKey":[]}],"x-required-scopes":["webhooks:read"],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},{"name":"cursor","in":"query","required":false,"schema":{"type":"string","maxLength":2000}}],"responses":{"200":{"description":"Success.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Subscription"}},"pagination":{"type":"object","additionalProperties":false,"properties":{"next_cursor":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}]},"has_more":{"type":"boolean"}},"required":["next_cursor","has_more"]},"request_id":{"type":"string","maxLength":180}},"required":["data","pagination","request_id"]},"example":{"data":[],"pagination":{"next_cursor":"example","has_more":false},"request_id":"example"}}}},"400":{"description":"Structured 400 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"401":{"description":"Structured 401 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_api_key","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"403":{"description":"Structured 403 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"404":{"description":"Structured 404 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"429":{"description":"Structured 429 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":true}}}}},"500":{"description":"Structured 500 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"503":{"description":"Structured 503 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":true}}}}}}},"post":{"operationId":"createSubscription","summary":"create subscription","description":"P0. Requires webhooks:manage. Every mutation requires Idempotency-Key; seven-day response retention, current authorization rechecked. Subscription event scopes and grants are rechecked. Signing secrets use protected one-hour encrypted response recovery; later replay returns secret_response_expired.","tags":["Public v1"],"security":[{"ApiKey":[]}],"x-required-scopes":["webhooks:manage"],"parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":8,"maxLength":128,"pattern":"^[ -~]+$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionWrite"},"example":{"url":"https://merchant.example/hooks/wingsflow","events":["message.received"],"schema_version":"1"}}}},"responses":{"201":{"description":"Created.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SubscriptionCreated"},"request_id":{"type":"string","maxLength":180}},"required":["data","request_id"]},"example":{"data":{"id":"11111111-1111-4111-8111-111111111111","url":"https://merchant.example/hooks/wingsflow","events":[],"state":"pending_verification","schema_version":"1","version":1,"verification_error":"example","signing_secret":"whsec_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","secret_version":1,"activated_at":"2026-09-14T06:30:00Z","previous_secret_expires_at":"2026-09-14T06:30:00Z"},"request_id":"example"}}}},"400":{"description":"Structured 400 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"401":{"description":"Structured 401 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_api_key","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"403":{"description":"Structured 403 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"404":{"description":"Structured 404 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"409":{"description":"Structured 409 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"413":{"description":"Structured 413 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"415":{"description":"Structured 415 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"422":{"description":"Structured 422 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"429":{"description":"Structured 429 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":true}}}}},"500":{"description":"Structured 500 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"503":{"description":"Structured 503 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":true}}}}}}}},"/webhook-subscriptions/{subscription_id}":{"patch":{"operationId":"updateSubscription","summary":"update subscription","description":"P0. Requires webhooks:manage. Every mutation requires Idempotency-Key; seven-day response retention, current authorization rechecked. Subscription event scopes and grants are rechecked. Signing secrets use protected one-hour encrypted response recovery; later replay returns secret_response_expired.","tags":["Public v1"],"security":[{"ApiKey":[]}],"x-required-scopes":["webhooks:manage"],"parameters":[{"name":"subscription_id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":8,"maxLength":128,"pattern":"^[ -~]+$"}},{"name":"If-Match","in":"header","required":true,"schema":{"type":"string","pattern":"^\"[1-9][0-9]*\"$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionPatch"},"example":{"enabled":true}}}},"responses":{"200":{"description":"Success.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Subscription"},"request_id":{"type":"string","maxLength":180}},"required":["data","request_id"]},"example":{"data":{"id":"11111111-1111-4111-8111-111111111111","url":"https://merchant.example/hooks/wingsflow","events":[],"state":"pending_verification","schema_version":"1","version":1,"verification_error":"example"},"request_id":"example"}}}},"400":{"description":"Structured 400 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"401":{"description":"Structured 401 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_api_key","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"403":{"description":"Structured 403 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"404":{"description":"Structured 404 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"409":{"description":"Structured 409 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"412":{"description":"Structured 412 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"413":{"description":"Structured 413 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"415":{"description":"Structured 415 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"422":{"description":"Structured 422 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"428":{"description":"Structured 428 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"429":{"description":"Structured 429 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":true}}}}},"500":{"description":"Structured 500 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"503":{"description":"Structured 503 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":true}}}}}}}},"/webhook-subscriptions/{subscription_id}/rotate-secret":{"post":{"operationId":"rotateSubscriptionSecret","summary":"rotate subscription secret","description":"P0. Requires webhooks:manage. Every mutation requires Idempotency-Key; seven-day response retention, current authorization rechecked. Subscription event scopes and grants are rechecked. Signing secrets use protected one-hour encrypted response recovery; later replay returns secret_response_expired.","tags":["Public v1"],"security":[{"ApiKey":[]}],"x-required-scopes":["webhooks:manage"],"parameters":[{"name":"subscription_id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":8,"maxLength":128,"pattern":"^[ -~]+$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Rotate"},"example":{"overlap_seconds":0}}}},"responses":{"200":{"description":"Success.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/SubscriptionCreated"},"request_id":{"type":"string","maxLength":180}},"required":["data","request_id"]},"example":{"data":{"id":"11111111-1111-4111-8111-111111111111","url":"https://merchant.example/hooks/wingsflow","events":[],"state":"pending_verification","schema_version":"1","version":1,"verification_error":"example","signing_secret":"whsec_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","secret_version":1,"activated_at":"2026-09-14T06:30:00Z","previous_secret_expires_at":"2026-09-14T06:30:00Z"},"request_id":"example"}}}},"400":{"description":"Structured 400 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"401":{"description":"Structured 401 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_api_key","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"403":{"description":"Structured 403 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"404":{"description":"Structured 404 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"409":{"description":"Structured 409 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"413":{"description":"Structured 413 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"415":{"description":"Structured 415 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"422":{"description":"Structured 422 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"429":{"description":"Structured 429 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":true}}}}},"500":{"description":"Structured 500 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"503":{"description":"Structured 503 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":true}}}}}}}},"/webhook-deliveries":{"get":{"operationId":"listDeliveries","summary":"list deliveries","description":"P0. Requires webhooks:read. Read is tenant and grant scoped.","tags":["Public v1"],"security":[{"ApiKey":[]}],"x-required-scopes":["webhooks:read"],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},{"name":"cursor","in":"query","required":false,"schema":{"type":"string","maxLength":2000}},{"name":"subscription_id","in":"query","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"event_id","in":"query","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"state","in":"query","required":false,"schema":{"type":"string","enum":["pending","in_flight","retry_scheduled","succeeded","failed","dead_letter","cancelled"]}}],"responses":{"200":{"description":"Success.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Delivery"}},"pagination":{"type":"object","additionalProperties":false,"properties":{"next_cursor":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}]},"has_more":{"type":"boolean"}},"required":["next_cursor","has_more"]},"request_id":{"type":"string","maxLength":180}},"required":["data","pagination","request_id"]},"example":{"data":[],"pagination":{"next_cursor":"example","has_more":false},"request_id":"example"}}}},"400":{"description":"Structured 400 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"401":{"description":"Structured 401 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_api_key","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"403":{"description":"Structured 403 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"404":{"description":"Structured 404 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"429":{"description":"Structured 429 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":true}}}}},"500":{"description":"Structured 500 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"503":{"description":"Structured 503 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":true}}}}}}}},"/webhook-deliveries/{delivery_id}/replay":{"post":{"operationId":"replayDelivery","summary":"replay delivery","description":"P0. Requires webhooks:manage. Every mutation requires Idempotency-Key; seven-day response retention, current authorization rechecked.","tags":["Public v1"],"security":[{"ApiKey":[]}],"x-required-scopes":["webhooks:manage"],"parameters":[{"name":"delivery_id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":8,"maxLength":128,"pattern":"^[ -~]+$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Empty"},"example":{}}}},"responses":{"202":{"description":"Durably admitted, not delivered.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/Replay"},"request_id":{"type":"string","maxLength":180}},"required":["data","request_id"]},"example":{"data":{"id":"11111111-1111-4111-8111-111111111111","event_id":"11111111-1111-4111-8111-111111111111","subscription_id":"11111111-1111-4111-8111-111111111111","state":"pending","replay_of":"11111111-1111-4111-8111-111111111111"},"request_id":"example"}}}},"400":{"description":"Structured 400 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"401":{"description":"Structured 401 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_api_key","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"403":{"description":"Structured 403 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"404":{"description":"Structured 404 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"409":{"description":"Structured 409 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"413":{"description":"Structured 413 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"415":{"description":"Structured 415 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"422":{"description":"Structured 422 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"429":{"description":"Structured 429 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":true}}}}},"500":{"description":"Structured 500 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":false}}}}},"503":{"description":"Structured 503 error. See error catalog and retry rules.","headers":{"X-Request-Id":{"schema":{"type":"string","maxLength":180}},"X-RateLimit-Limit":{"schema":{"type":"integer","minimum":1}},"X-RateLimit-Remaining":{"schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"schema":{"type":"integer","minimum":1}},"Retry-After":{"schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"invalid_request","message":"Request rejected.","request_id":"req_example","retryable":true}}}}}}}}},"components":{"securitySchemes":{"ApiKey":{"type":"http","scheme":"bearer","bearerFormat":"Opaque tenant/environment-bound API key"}},"schemas":{"Error":{"type":"object","additionalProperties":false,"properties":{"error":{"type":"object","additionalProperties":false,"properties":{"code":{"type":"string","maxLength":180},"message":{"type":"string","maxLength":500},"retryable":{"type":"boolean"},"request_id":{"type":"string","maxLength":180}},"required":["code","message","retryable","request_id"]}},"required":["error"]},"ContactWrite":{"type":"object","additionalProperties":false,"properties":{"phone":{"type":"string","pattern":"^\\+[1-9][0-9]{7,14}$"},"name":{"type":"string","maxLength":180},"tags":{"type":"array","maxItems":20,"items":{"type":"string","maxLength":40}},"source":{"type":"string","maxLength":180}},"required":["phone"]},"Contact":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","format":"uuid"},"external_id":{"type":["string","null"]},"phone":{"type":"string","pattern":"^\\+[1-9][0-9]{7,14}$"},"name":{"type":["string","null"]},"version":{"type":"integer","minimum":1},"suppressed":{"type":"boolean"},"tags":{"type":"array","items":{"type":"string"}},"consents":{"type":"object","additionalProperties":false,"properties":{"service":{"$ref":"#/components/schemas/EffectiveConsent"},"marketing":{"$ref":"#/components/schemas/EffectiveConsent"}},"required":["service","marketing"]}},"required":["id","external_id","phone","name","version","suppressed","tags","consents"]},"Consent":{"type":"object","additionalProperties":false,"properties":{"purpose":{"type":"string","enum":["service","marketing"]},"action":{"type":"string","enum":["opt_in","opt_out"]},"source":{"type":"string","minLength":1,"maxLength":180},"evidence_reference":{"type":"string","minLength":1,"maxLength":2000},"occurred_at":{"type":"string","format":"date-time"}},"required":["purpose","action","source","evidence_reference","occurred_at"]},"ConsentReceipt":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","format":"uuid"},"contact_id":{"type":"string","format":"uuid"},"received_at":{"type":"string","format":"date-time"},"effective_action":{"type":"string","enum":["opt_in","opt_out"]},"effective_at":{"type":"string","format":"date-time"},"applied":{"type":"boolean"}},"required":["id","contact_id","received_at","effective_action","effective_at","applied"]},"Channel":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","format":"uuid"},"display_phone":{"anyOf":[{"type":"string","pattern":"^\\+[1-9][0-9]{7,14}$"},{"type":"null"}],"description":"Null when provider metadata has no verified display phone. Never fabricated."},"provider":{"type":"string"},"state":{"type":"string"},"capabilities":{"type":"array","items":{"type":"string"}}},"required":["id","display_phone","provider","state","capabilities"]},"Identity":{"type":"object","additionalProperties":false,"properties":{"tenant_id":{"type":"string","format":"uuid"},"integration_id":{"type":"string","format":"uuid"},"environment":{"type":"string","enum":["test","live"]},"scopes":{"type":"array","items":{"type":"string","enum":["channels:read","contacts:read","contacts:write","consents:write","templates:read","messages:write","messages:read","messages:content:read","events:write","events:read","webhooks:read","webhooks:manage"]}},"allowed_channel_ids":{"type":"array","items":{"type":"string","format":"uuid"}},"allowed_template_ids":{"type":"array","items":{"type":"string","format":"uuid"}},"capabilities":{"type":"array","items":{"type":"string","maxLength":180}}},"required":["tenant_id","integration_id","environment","scopes","allowed_channel_ids","allowed_template_ids","capabilities"]},"Text":{"type":"object","additionalProperties":false,"properties":{"type":{"const":"text"},"conversation_id":{"type":"string","format":"uuid"},"text":{"type":"string","minLength":1,"maxLength":4096}},"required":["type","conversation_id","text"]},"Template":{"type":"object","additionalProperties":false,"properties":{"type":{"const":"template"},"template_id":{"type":"string","format":"uuid"},"template_version":{"type":"integer","minimum":1},"language":{"type":"string","minLength":2,"maxLength":20},"parameters":{"type":"object","maxProperties":30,"additionalProperties":{"type":"string","maxLength":4096}}},"required":["type","template_id","template_version","language","parameters"]},"MessageWrite":{"type":"object","additionalProperties":false,"properties":{"channel_id":{"type":"string","format":"uuid"},"contact_id":{"type":"string","format":"uuid"},"client_reference":{"type":"string","minLength":1,"maxLength":180},"message":{"oneOf":[{"$ref":"#/components/schemas/Text"},{"$ref":"#/components/schemas/Template"}]}},"required":["channel_id","contact_id","client_reference","message"]},"Message":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["queued","dispatching","accepted","sent","delivered","read","failed","blocked","unknown","cancelled"]},"version":{"type":"integer","minimum":1},"client_reference":{"type":"string","maxLength":180},"channel_id":{"type":"string","format":"uuid"},"contact_id":{"type":"string","format":"uuid"},"conversation_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}]},"correlation_id":{"anyOf":[{"type":"string","maxLength":180},{"type":"null"}]},"error":{"anyOf":[{"$ref":"#/components/schemas/SafeError"},{"type":"null"}]}},"required":["id","status","version","client_reference","channel_id","contact_id","conversation_id","correlation_id","error"]},"EventCustomer":{"type":"object","additionalProperties":false,"properties":{"external_id":{"type":"string","minLength":1,"maxLength":180},"phone":{"type":"string","pattern":"^\\+[1-9][0-9]{7,14}$"},"name":{"type":"string","maxLength":180}},"required":["external_id","phone"]},"EventWrite":{"type":"object","additionalProperties":false,"properties":{"source_event_id":{"type":"string","minLength":1,"maxLength":180},"event":{"type":"string","pattern":"^[a-z][a-z0-9_]*(\\.[a-z][a-z0-9_]*)+$","maxLength":120},"schema_version":{"const":"1"},"occurred_at":{"type":"string","format":"date-time"},"customer":{"$ref":"#/components/schemas/EventCustomer"},"contact_id":{"type":"string","format":"uuid"},"data":{"type":"object","additionalProperties":true,"description":"Bounded to 32 KiB and 8 levels; validated against configured event schema before execution."},"correlation_id":{"type":"string","maxLength":180}},"required":["source_event_id","event","schema_version","occurred_at","data"],"not":{"required":["customer","contact_id"]}},"Event":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["received","processing","processed","no_matching_binding","blocked","failed"]},"message_ids":{"type":"array","items":{"type":"string","format":"uuid"},"maxItems":1},"outcome":{"anyOf":[{"$ref":"#/components/schemas/Outcome"},{"type":"null"}]},"error":{"anyOf":[{"$ref":"#/components/schemas/SafeError"},{"type":"null"}]}},"required":["id","status","message_ids","outcome","error"]},"SubscriptionWrite":{"type":"object","additionalProperties":false,"properties":{"url":{"type":"string","format":"uri","pattern":"^https://","maxLength":2048},"events":{"type":"array","minItems":1,"maxItems":30,"uniqueItems":true,"items":{"type":"string","enum":["message.received","message.accepted","message.sent","message.delivered","message.read","message.failed","message.blocked","message.unknown","message.cancelled","integration_event.processed","integration_event.failed"]}},"schema_version":{"const":"1"},"description":{"type":"string","maxLength":180}},"required":["url","events","schema_version"]},"Subscription":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","format":"uuid"},"url":{"type":"string","format":"uri"},"events":{"type":"array","items":{"type":"string","enum":["message.received","message.accepted","message.sent","message.delivered","message.read","message.failed","message.blocked","message.unknown","message.cancelled","integration_event.processed","integration_event.failed"]}},"state":{"type":"string","enum":["pending_verification","enabled","disabled"]},"schema_version":{"const":"1"},"version":{"type":"integer","minimum":1},"verification_error":{"anyOf":[{"type":"string","maxLength":180},{"type":"null"}]}},"required":["id","url","events","state","schema_version","version","verification_error"]},"SubscriptionPatch":{"type":"object","additionalProperties":false,"properties":{"enabled":{"type":"boolean"},"url":{"type":"string","format":"uri","pattern":"^https://","maxLength":2048},"events":{"type":"array","minItems":1,"maxItems":30,"uniqueItems":true,"items":{"type":"string","enum":["message.received","message.accepted","message.sent","message.delivered","message.read","message.failed","message.blocked","message.unknown","message.cancelled","integration_event.processed","integration_event.failed"]}}},"required":[],"minProperties":1},"DomainEvent":{"oneOf":[{"$ref":"#/components/schemas/MessageStatusEvent"},{"$ref":"#/components/schemas/InboundEvent"},{"$ref":"#/components/schemas/ProcessedEvent"},{"$ref":"#/components/schemas/FailedEvent"}]},"SubscriptionCreated":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","format":"uuid"},"url":{"type":"string","format":"uri"},"events":{"type":"array","items":{"type":"string","enum":["message.received","message.accepted","message.sent","message.delivered","message.read","message.failed","message.blocked","message.unknown","message.cancelled","integration_event.processed","integration_event.failed"]}},"state":{"type":"string","enum":["pending_verification","enabled","disabled"]},"schema_version":{"const":"1"},"version":{"type":"integer","minimum":1},"verification_error":{"anyOf":[{"type":"string","maxLength":180},{"type":"null"}]},"signing_secret":{"type":"string","pattern":"^whsec_[A-Za-z0-9_-]{43}$"},"secret_version":{"type":"integer","minimum":1},"activated_at":{"type":"string","format":"date-time"},"previous_secret_expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]}},"required":["id","url","events","state","schema_version","version","verification_error","signing_secret","secret_version","activated_at","previous_secret_expires_at"]},"SafeError":{"type":"object","additionalProperties":false,"properties":{"code":{"type":"string","maxLength":180},"message":{"type":"string","maxLength":500},"retryable":{"type":"boolean"}},"required":["code","message","retryable"]},"EffectiveConsent":{"type":"object","additionalProperties":false,"properties":{"action":{"anyOf":[{"type":"string","enum":["opt_in","opt_out"]},{"type":"null"}]},"occurred_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]}},"required":["action","occurred_at"]},"TemplateResource":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","format":"uuid"},"version":{"type":"integer","minimum":1},"channel_id":{"type":"string","format":"uuid"},"name":{"type":"string","maxLength":180},"language":{"type":"string","maxLength":20},"purpose":{"type":"string","enum":["service","marketing"]},"status":{"type":"string","enum":["approved","pending","rejected","paused","disabled"]},"parameters":{"type":"array","items":{"type":"object","additionalProperties":false,"properties":{"name":{"type":"string","maxLength":180},"type":{"const":"string"},"required":{"type":"boolean"}},"required":["name","type","required"]}},"updated_at":{"type":"string","format":"date-time"}},"required":["id","version","channel_id","name","language","purpose","status","parameters","updated_at"]},"Outcome":{"type":"object","additionalProperties":false,"properties":{"binding_id":{"type":"string","format":"uuid"},"binding_version":{"type":"integer","minimum":1},"reason_code":{"type":"string","maxLength":180}},"required":["binding_id","binding_version","reason_code"]},"Rotate":{"type":"object","additionalProperties":false,"properties":{"overlap_seconds":{"type":"integer","enum":[0,86400]}},"required":["overlap_seconds"]},"Empty":{"type":"object","additionalProperties":false,"properties":{},"required":[]},"Attempt":{"type":"object","additionalProperties":false,"properties":{"number":{"type":"integer","minimum":1},"started_at":{"type":"string","format":"date-time"},"completed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"http_status":{"anyOf":[{"type":"integer","minimum":100,"maximum":599},{"type":"null"}]},"error_code":{"anyOf":[{"type":"string","maxLength":180},{"type":"null"}]},"latency_ms":{"type":"integer","minimum":0}},"required":["number","started_at","completed_at","http_status","error_code","latency_ms"]},"Delivery":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","format":"uuid"},"event_id":{"type":"string","format":"uuid"},"subscription_id":{"type":"string","format":"uuid"},"destination_version":{"type":"integer","minimum":1},"state":{"type":"string","enum":["pending","in_flight","retry_scheduled","succeeded","failed","dead_letter","cancelled"]},"attempt_count":{"type":"integer","minimum":0,"maximum":9},"next_attempt_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"last_status":{"anyOf":[{"type":"integer"},{"type":"null"}]},"error":{"anyOf":[{"type":"string","maxLength":180},{"type":"null"}]},"created_at":{"type":"string","format":"date-time"},"completed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"attempts":{"type":"array","items":{"$ref":"#/components/schemas/Attempt"},"maxItems":9}},"required":["id","event_id","subscription_id","destination_version","state","attempt_count","next_attempt_at","last_status","error","created_at","completed_at","attempts"]},"Replay":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","format":"uuid"},"event_id":{"type":"string","format":"uuid"},"subscription_id":{"type":"string","format":"uuid"},"state":{"const":"pending"},"replay_of":{"type":"string","format":"uuid"}},"required":["id","event_id","subscription_id","state","replay_of"]},"MessageStatusEvent":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","format":"uuid"},"type":{"type":"string","enum":["message.accepted","message.sent","message.delivered","message.read","message.failed","message.blocked","message.unknown","message.cancelled"]},"schema_version":{"const":"1"},"occurred_at":{"type":"string","format":"date-time"},"tenant_id":{"type":"string","format":"uuid"},"resource":{"type":"object","additionalProperties":false,"properties":{"type":{"const":"message"},"id":{"type":"string","format":"uuid"},"version":{"type":"integer","minimum":1}},"required":["type","id","version"]},"correlation_id":{"anyOf":[{"type":"string","maxLength":180},{"type":"null"}]},"causation_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}]},"data":{"type":"object","additionalProperties":false,"properties":{"status":{"type":"string","enum":["accepted","sent","delivered","read","failed","blocked","unknown","cancelled"]},"client_reference":{"type":"string","maxLength":180},"channel_id":{"type":"string","format":"uuid"},"contact_id":{"type":"string","format":"uuid"},"conversation_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}]},"error":{"anyOf":[{"$ref":"#/components/schemas/SafeError"},{"type":"null"}]}},"required":["status","client_reference","channel_id","contact_id","conversation_id","error"]}},"required":["id","type","schema_version","occurred_at","tenant_id","resource","correlation_id","causation_id","data"],"examples":[{"id":"11111111-1111-4111-8111-111111111111","type":"message.accepted","schema_version":"1","occurred_at":"2026-09-14T06:30:00Z","tenant_id":"11111111-1111-4111-8111-111111111111","resource":{"type":"message","id":"11111111-1111-4111-8111-111111111111","version":1},"correlation_id":"example","causation_id":"11111111-1111-4111-8111-111111111111","data":{"status":"accepted","client_reference":"example","channel_id":"11111111-1111-4111-8111-111111111111","contact_id":"11111111-1111-4111-8111-111111111111","conversation_id":"11111111-1111-4111-8111-111111111111","error":{"code":"example","message":"example","retryable":false}}}]},"InboundEvent":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","format":"uuid"},"type":{"const":"message.received"},"schema_version":{"const":"1"},"occurred_at":{"type":"string","format":"date-time"},"tenant_id":{"type":"string","format":"uuid"},"resource":{"type":"object","additionalProperties":false,"properties":{"type":{"const":"message"},"id":{"type":"string","format":"uuid"},"version":{"type":"integer","minimum":1}},"required":["type","id","version"]},"correlation_id":{"anyOf":[{"type":"string","maxLength":180},{"type":"null"}]},"causation_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}]},"data":{"type":"object","additionalProperties":false,"properties":{"channel_id":{"type":"string","format":"uuid"},"contact_id":{"type":"string","format":"uuid"},"conversation_id":{"type":"string","format":"uuid"},"message_type":{"type":"string","enum":["text","unsupported"]},"text":{"type":"string","maxLength":4096}},"required":["channel_id","contact_id","conversation_id","message_type"],"allOf":[{"if":{"properties":{"message_type":{"const":"unsupported"}}},"then":{"not":{"required":["text"]}}}]}},"required":["id","type","schema_version","occurred_at","tenant_id","resource","correlation_id","causation_id","data"],"examples":[{"id":"11111111-1111-4111-8111-111111111111","type":"message.received","schema_version":"1","occurred_at":"2026-09-14T06:30:00Z","tenant_id":"11111111-1111-4111-8111-111111111111","resource":{"type":"message","id":"11111111-1111-4111-8111-111111111111","version":1},"correlation_id":"example","causation_id":"11111111-1111-4111-8111-111111111111","data":{"channel_id":"11111111-1111-4111-8111-111111111111","contact_id":"11111111-1111-4111-8111-111111111111","conversation_id":"11111111-1111-4111-8111-111111111111","message_type":"text"}}]},"ProcessedEvent":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","format":"uuid"},"type":{"const":"integration_event.processed"},"schema_version":{"const":"1"},"occurred_at":{"type":"string","format":"date-time"},"tenant_id":{"type":"string","format":"uuid"},"resource":{"type":"object","additionalProperties":false,"properties":{"type":{"const":"integration_event"},"id":{"type":"string","format":"uuid"},"version":{"type":"integer","minimum":1}},"required":["type","id","version"]},"correlation_id":{"anyOf":[{"type":"string","maxLength":180},{"type":"null"}]},"causation_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}]},"data":{"type":"object","additionalProperties":false,"properties":{"source_event_id":{"type":"string","maxLength":180},"event":{"type":"string","maxLength":120},"status":{"type":"string","enum":["processed","no_matching_binding"]},"message_ids":{"type":"array","items":{"type":"string","format":"uuid"}},"outcome":{"anyOf":[{"$ref":"#/components/schemas/Outcome"},{"type":"null"}]}},"required":["source_event_id","event","status","message_ids","outcome"]}},"required":["id","type","schema_version","occurred_at","tenant_id","resource","correlation_id","causation_id","data"],"examples":[{"id":"11111111-1111-4111-8111-111111111111","type":"integration_event.processed","schema_version":"1","occurred_at":"2026-09-14T06:30:00Z","tenant_id":"11111111-1111-4111-8111-111111111111","resource":{"type":"integration_event","id":"11111111-1111-4111-8111-111111111111","version":1},"correlation_id":"example","causation_id":"11111111-1111-4111-8111-111111111111","data":{"source_event_id":"example","event":"example","status":"processed","message_ids":[],"outcome":{"binding_id":"11111111-1111-4111-8111-111111111111","binding_version":1,"reason_code":"example"}}}]},"FailedEvent":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","format":"uuid"},"type":{"const":"integration_event.failed"},"schema_version":{"const":"1"},"occurred_at":{"type":"string","format":"date-time"},"tenant_id":{"type":"string","format":"uuid"},"resource":{"type":"object","additionalProperties":false,"properties":{"type":{"const":"integration_event"},"id":{"type":"string","format":"uuid"},"version":{"type":"integer","minimum":1}},"required":["type","id","version"]},"correlation_id":{"anyOf":[{"type":"string","maxLength":180},{"type":"null"}]},"causation_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}]},"data":{"type":"object","additionalProperties":false,"properties":{"source_event_id":{"type":"string","maxLength":180},"event":{"type":"string","maxLength":120},"status":{"type":"string","enum":["failed","blocked"]},"message_ids":{"type":"array","items":{"type":"string","format":"uuid"}},"outcome":{"anyOf":[{"$ref":"#/components/schemas/Outcome"},{"type":"null"}]},"error":{"$ref":"#/components/schemas/SafeError"}},"required":["source_event_id","event","status","message_ids","outcome","error"]}},"required":["id","type","schema_version","occurred_at","tenant_id","resource","correlation_id","causation_id","data"],"examples":[{"id":"11111111-1111-4111-8111-111111111111","type":"integration_event.failed","schema_version":"1","occurred_at":"2026-09-14T06:30:00Z","tenant_id":"11111111-1111-4111-8111-111111111111","resource":{"type":"integration_event","id":"11111111-1111-4111-8111-111111111111","version":1},"correlation_id":"example","causation_id":"11111111-1111-4111-8111-111111111111","data":{"source_event_id":"example","event":"example","status":"failed","message_ids":[],"outcome":{"binding_id":"11111111-1111-4111-8111-111111111111","binding_version":1,"reason_code":"example"},"error":{"code":"example","message":"example","retryable":false}}}]},"Verification":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","format":"uuid"},"type":{"const":"endpoint.verification"},"schema_version":{"const":"1"},"occurred_at":{"type":"string","format":"date-time"},"tenant_id":{"type":"string","format":"uuid"},"resource":{"type":"object","additionalProperties":false,"properties":{"type":{"const":"webhook_subscription"},"id":{"type":"string","format":"uuid"},"version":{"type":"integer","minimum":1}},"required":["type","id","version"]},"correlation_id":{"anyOf":[{"type":"string","maxLength":180},{"type":"null"}]},"causation_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}]},"data":{"type":"object","additionalProperties":false,"properties":{"challenge":{"type":"string","pattern":"^[A-Za-z0-9_-]{43}$"},"expires_at":{"type":"string","format":"date-time"}},"required":["challenge","expires_at"]}},"required":["id","type","schema_version","occurred_at","tenant_id","resource","correlation_id","causation_id","data"],"examples":[{"id":"11111111-1111-4111-8111-111111111111","type":"endpoint.verification","schema_version":"1","occurred_at":"2026-09-14T06:30:00Z","tenant_id":"11111111-1111-4111-8111-111111111111","resource":{"type":"webhook_subscription","id":"11111111-1111-4111-8111-111111111111","version":1},"correlation_id":"example","causation_id":"11111111-1111-4111-8111-111111111111","data":{"challenge":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","expires_at":"2026-09-14T06:30:00Z"}}]},"ChallengeEcho":{"type":"object","additionalProperties":false,"properties":{"challenge":{"type":"string","pattern":"^[A-Za-z0-9_-]{43}$"}},"required":["challenge"]},"OrderData":{"type":"object","additionalProperties":false,"properties":{"order_id":{"type":"string","maxLength":180,"minLength":1},"aggregate_version":{"type":"integer","minimum":1},"amount_minor":{"type":"integer","minimum":0},"currency":{"type":"string","pattern":"^[A-Z]{3}$"}},"required":["order_id","aggregate_version","amount_minor","currency"]},"CustomerData":{"type":"object","additionalProperties":false,"properties":{"customer_id":{"type":"string","maxLength":180,"minLength":1},"aggregate_version":{"type":"integer","minimum":1}},"required":["customer_id","aggregate_version"]},"PaymentData":{"type":"object","additionalProperties":false,"properties":{"payment_id":{"type":"string","maxLength":180,"minLength":1},"order_id":{"type":"string","maxLength":180,"minLength":1},"aggregate_version":{"type":"integer","minimum":1},"amount_minor":{"type":"integer","minimum":0},"currency":{"type":"string","pattern":"^[A-Z]{3}$"}},"required":["payment_id","order_id","aggregate_version","amount_minor","currency"]}}},"webhooks":{"canonicalEvent":{"post":{"operationId":"receiveWingsFlowEvent","summary":"Signed business notification","security":[],"parameters":[{"name":"WingsFlow-Event-Id","in":"header","required":true,"schema":{"type":"string","maxLength":500}},{"name":"WingsFlow-Delivery-Id","in":"header","required":true,"schema":{"type":"string","maxLength":500}},{"name":"WingsFlow-Timestamp","in":"header","required":true,"schema":{"type":"string","maxLength":500}},{"name":"WingsFlow-Signature","in":"header","required":true,"schema":{"type":"string","maxLength":500}}],"description":"HMAC-SHA256(timestamp.delivery_id.event_id.raw_body), UTF-8 secret. Timestamp tolerance ±300s. Verify raw bytes and expected tenant before durable inbox dedupe and acknowledgment. No ordering guarantee.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DomainEvent"},"example":{"id":"11111111-1111-4111-8111-111111111111","type":"message.accepted","schema_version":"1","occurred_at":"2026-09-14T06:30:00Z","tenant_id":"11111111-1111-4111-8111-111111111111","resource":{"type":"message","id":"11111111-1111-4111-8111-111111111111","version":1},"correlation_id":"example","causation_id":"11111111-1111-4111-8111-111111111111","data":{"status":"accepted","client_reference":"example","channel_id":"11111111-1111-4111-8111-111111111111","contact_id":"11111111-1111-4111-8111-111111111111","conversation_id":"11111111-1111-4111-8111-111111111111","error":{"code":"example","message":"example","retryable":false}}}}}},"responses":{"200":{"description":"Durably persisted/deduplicated"},"204":{"description":"Durably persisted/deduplicated"},"401":{"description":"Signature or timestamp invalid"},"429":{"description":"Retry with bounded Retry-After"},"503":{"description":"Receiver unavailable; retry"},"default":{"description":"408/429/5xx/transport retry; other 4xx terminal, 410 disables; 3xx never followed. Nine attempts within 72h."}}}},"endpointVerification":{"post":{"operationId":"verifyEndpoint","summary":"Signed endpoint verification","security":[],"parameters":[{"name":"WingsFlow-Event-Id","in":"header","required":true,"schema":{"type":"string","maxLength":500}},{"name":"WingsFlow-Delivery-Id","in":"header","required":true,"schema":{"type":"string","maxLength":500}},{"name":"WingsFlow-Timestamp","in":"header","required":true,"schema":{"type":"string","maxLength":500}},{"name":"WingsFlow-Signature","in":"header","required":true,"schema":{"type":"string","maxLength":500}}],"description":"HMAC-SHA256(timestamp.delivery_id.event_id.raw_body), UTF-8 secret. Timestamp tolerance ±300s. Verify raw bytes and expected tenant before durable inbox dedupe and acknowledgment. No ordering guarantee.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Verification"},"example":{"id":"11111111-1111-4111-8111-111111111111","type":"endpoint.verification","schema_version":"1","occurred_at":"2026-09-14T06:30:00Z","tenant_id":"11111111-1111-4111-8111-111111111111","resource":{"type":"webhook_subscription","id":"11111111-1111-4111-8111-111111111111","version":1},"correlation_id":"example","causation_id":"11111111-1111-4111-8111-111111111111","data":{"challenge":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","expires_at":"2026-09-14T06:30:00Z"}}}}},"responses":{"200":{"description":"Exact challenge echo","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChallengeEcho"},"example":{"challenge":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}}}},"401":{"description":"Signature or timestamp invalid"},"429":{"description":"Retry with bounded Retry-After"},"503":{"description":"Receiver unavailable; retry"},"default":{"description":"408/429/5xx/transport retry; other 4xx terminal, 410 disables; 3xx never followed. Nine attempts within 72h."}}}}}}