{"openapi":"3.1.2","info":{"title":"Webhook Service API","description":"API for managing webhooks","version":"1.1.0","contact":{"name":"e.bilovol@sendpulse.com"}},"servers":[{"url":"https:\/\/api.sendpulse.com\/webhooks","description":"Production server"}],"tags":[{"name":"Webhooks","description":"Managing webhooks, their events, delivery logs and settings"}],"paths":{"\/webhooks":{"get":{"tags":["Webhooks"],"summary":"Get a list of webhooks","description":"Returns the current user's webhooks with optional filtering, search and sorting","operationId":"getWebhooks","parameters":[{"name":"status","in":"query","description":"Filter by status (1 = ACTIVE, 0 = INACTIVE, 2 = DISABLED_AUTO)","required":false,"schema":{"type":"integer","enum":[0,1,2],"example":1}},{"name":"search","in":"query","description":"Case-sensitive substring match against the webhook URL","required":false,"schema":{"type":"string","maxLength":255,"example":"example.com"}},{"name":"order","in":"query","description":"Sort order","required":false,"schema":{"type":"string","enum":["asc","desc"],"default":"asc","example":"desc"}},{"name":"order_by","in":"query","description":"Sort field","required":false,"schema":{"type":"string","enum":["id","status","created_at","updated_at"],"default":"id","example":"created_at"}}],"responses":{"200":{"description":"Successful response","content":{"application\/json":{"schema":{"type":"object","properties":{"result":{"type":"boolean","example":true},"data":{"type":"array","items":{"$ref":"#\/components\/schemas\/Webhook"}}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"422":{"description":"Validation error","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"},"examples":{"invalidStatus":{"summary":"Invalid status value","value":{"result":false,"data":null,"error":"Param status is unsupported","code":4409}}}}}}}},"post":{"tags":["Webhooks"],"summary":"Create a webhook","description":"Creates a new webhook subscribed to one or more active events","operationId":"createWebhook","requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/WebhookCreateRequest"},"example":{"name":"My integration","url":"https:\/\/example.com\/webhook-endpoint","events":[11,12],"status":1,"address_book_id":[1113605],"headers":[{"name":"X-Custom-Token","value":"s3cr3t"}]}}}},"responses":{"200":{"description":"Webhook successfully created","content":{"application\/json":{"schema":{"type":"object","properties":{"result":{"type":"boolean","example":true},"data":{"$ref":"#\/components\/schemas\/Webhook"}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"422":{"description":"Validation error","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"},"examples":{"invalidName":{"summary":"Param name unsupported","value":{"result":false,"data":null,"error":"Param name is unsupported","code":4403}},"requireUrl":{"summary":"Param url required","value":{"result":false,"data":null,"error":"Param url is required","code":4404}},"invalidUrl":{"summary":"Param url must be a valid HTTPS URL","value":{"result":false,"data":null,"error":"Param url must be a valid HTTPS URL","code":4405}},"requireEvents":{"summary":"Param events required","value":{"result":false,"data":null,"error":"Param events is required","code":4406}},"invalidEvents":{"summary":"Param events unsupported","value":{"result":false,"data":null,"error":"Param events contains unsupported value","code":4407}},"urlDuplicate":{"summary":"Webhook url duplicate","value":{"result":false,"data":null,"error":"Webhook with this url already exists","code":4412}},"nameDuplicate":{"summary":"Webhook name duplicate","value":{"result":false,"data":null,"error":"Webhook with this name already exists","code":4413}},"invalidHeaders":{"summary":"Param headers unsupported","value":{"result":false,"data":null,"error":"Param headers must be a list of objects with name and value","code":4414}},"headersLimit":{"summary":"Too many headers","value":{"result":false,"data":null,"error":"Param headers must not contain more than 10 items","code":4415}},"invalidHeaderName":{"summary":"Param headers name unsupported","value":{"result":false,"data":null,"error":"Param headers name must be 1-128 characters of an RFC 7230 token","code":4416}},"invalidHeaderValue":{"summary":"Param headers value unsupported","value":{"result":false,"data":null,"error":"Param headers value must be 1-1024 printable ASCII characters","code":4417}},"duplicateHeaderName":{"summary":"Repeated header name","value":{"result":false,"data":null,"error":"Param headers must not repeat the same name","code":4418}},"forbiddenHeaderName":{"summary":"Reserved header name","value":{"result":false,"data":null,"error":"Param headers name is reserved and cannot be overridden","code":4419}},"headersSize":{"summary":"Headers too large","value":{"result":false,"data":null,"error":"Param headers must not exceed 8192 bytes in total","code":4420}},"urlScheme":{"summary":"Url must use https","value":{"result":false,"data":null,"error":"Param url must use the https scheme","code":4421}},"urlHostForbidden":{"summary":"Url host is not public","value":{"result":false,"data":null,"error":"Param url host is not a public domain name","code":4422}},"urlHostUnresolvable":{"summary":"Url host cannot be resolved","value":{"result":false,"data":null,"error":"Param url host cannot be resolved","code":4423}},"urlPrivateNetwork":{"summary":"Url resolves to a private address","value":{"result":false,"data":null,"error":"Param url resolves to a non-public network address","code":4424}},"urlBlocked":{"summary":"Url is not allowed","value":{"result":false,"data":null,"error":"Webhook url is not allowed","code":4434}}}}}}}}},"\/webhooks\/{webhook}":{"get":{"tags":["Webhooks"],"summary":"Get webhook by ID","description":"Returns a single webhook owned by the current user","operationId":"getWebhookById","parameters":[{"$ref":"#\/components\/parameters\/WebhookId"}],"responses":{"200":{"description":"Successful response","content":{"application\/json":{"schema":{"type":"object","properties":{"result":{"type":"boolean","example":true},"data":{"$ref":"#\/components\/schemas\/Webhook"}}}}}},"404":{"$ref":"#\/components\/responses\/WebhookNotFound"},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"}}},"post":{"tags":["Webhooks"],"summary":"Update webhook","description":"Updates the webhook. All fields are optional; only the fields sent are changed.\nA `name` sent as null (or empty) clears the stored name. A header value sent as null\nkeeps the value already stored for that header.\n","operationId":"updateWebhook","parameters":[{"$ref":"#\/components\/parameters\/WebhookId"}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/WebhookUpdateRequest"},"example":{"name":"Renamed integration","url":"https:\/\/example.com\/new-webhook-endpoint","events":[11],"headers":[{"name":"X-Custom-Token","value":null}]}}}},"responses":{"200":{"$ref":"#\/components\/responses\/SuccessNull"},"404":{"$ref":"#\/components\/responses\/WebhookNotFound"},"422":{"description":"Validation error","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"},"examples":{"invalidName":{"summary":"Param name unsupported","value":{"result":false,"data":null,"error":"Param name is unsupported","code":4403}},"invalidUrl":{"summary":"Param url must be a valid HTTPS URL","value":{"result":false,"data":null,"error":"Param url must be a valid HTTPS URL","code":4405}},"urlScheme":{"summary":"Url must use https","value":{"result":false,"data":null,"error":"Param url must use the https scheme","code":4421}},"urlHostForbidden":{"summary":"Url host is not public","value":{"result":false,"data":null,"error":"Param url host is not a public domain name","code":4422}},"urlHostUnresolvable":{"summary":"Url host cannot be resolved","value":{"result":false,"data":null,"error":"Param url host cannot be resolved","code":4423}},"urlPrivateNetwork":{"summary":"Url resolves to a private address","value":{"result":false,"data":null,"error":"Param url resolves to a non-public network address","code":4424}},"urlBlocked":{"summary":"Url is not allowed","value":{"result":false,"data":null,"error":"Webhook url is not allowed","code":4434}},"invalidEvents":{"summary":"Param events unsupported","value":{"result":false,"data":null,"error":"Param events contains unsupported value","code":4407}},"urlDuplicate":{"summary":"Webhook url duplicate","value":{"result":false,"data":null,"error":"Webhook with this url already exists","code":4412}},"nameDuplicate":{"summary":"Webhook name duplicate","value":{"result":false,"data":null,"error":"Webhook with this name already exists","code":4413}},"invalidHeaders":{"summary":"Param headers unsupported","value":{"result":false,"data":null,"error":"Param headers must be a list of objects with name and value","code":4414}},"headersLimit":{"summary":"Too many headers","value":{"result":false,"data":null,"error":"Param headers must not contain more than 10 items","code":4415}},"invalidHeaderName":{"summary":"Param headers name unsupported","value":{"result":false,"data":null,"error":"Param headers name must be 1-128 characters of an RFC 7230 token","code":4416}},"invalidHeaderValue":{"summary":"Param headers value unsupported","value":{"result":false,"data":null,"error":"Param headers value must be 1-1024 printable ASCII characters","code":4417}},"duplicateHeaderName":{"summary":"Repeated header name","value":{"result":false,"data":null,"error":"Param headers must not repeat the same name","code":4418}},"forbiddenHeaderName":{"summary":"Reserved header name","value":{"result":false,"data":null,"error":"Param headers name is reserved and cannot be overridden","code":4419}},"headersSize":{"summary":"Headers too large","value":{"result":false,"data":null,"error":"Param headers must not exceed 8192 bytes in total","code":4420}},"headerValueRequired":{"summary":"Header has no stored value to keep","value":{"result":false,"data":null,"error":"Param headers value is required for a header the webhook does not have yet","code":4425}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"}}},"delete":{"tags":["Webhooks"],"summary":"Delete webhook","description":"Deletes the webhook and all of its events","operationId":"deleteWebhook","parameters":[{"$ref":"#\/components\/parameters\/WebhookId"}],"responses":{"200":{"$ref":"#\/components\/responses\/SuccessNull"},"404":{"$ref":"#\/components\/responses\/WebhookNotFound"},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"}}}},"\/webhooks\/{webhook}\/status":{"post":{"tags":["Webhooks"],"summary":"Update webhook status","description":"Changes the webhook status (1 = active, 0 = inactive)","operationId":"updateWebhookStatus","parameters":[{"$ref":"#\/components\/parameters\/WebhookId"}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["status"],"properties":{"status":{"type":"integer","enum":[0,1],"description":"1 = ACTIVE, 0 = INACTIVE","example":1}}}}}},"responses":{"200":{"$ref":"#\/components\/responses\/SuccessNull"},"404":{"$ref":"#\/components\/responses\/WebhookNotFound"},"422":{"description":"Validation error","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"},"examples":{"requireStatus":{"summary":"Param status required","value":{"result":false,"data":null,"error":"Param status is required","code":4408}},"invalidStatus":{"summary":"Param status unsupported","value":{"result":false,"data":null,"error":"Param status is unsupported","code":4409}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"}}}},"\/webhooks\/{webhook}\/secret":{"post":{"tags":["Webhooks"],"summary":"Regenerate webhook secret","description":"Generates a new signing secret for the webhook. The new secret itself is not returned;\nfetch the webhook to read the updated `secret_key`.\n","operationId":"regenerateWebhookSecret","parameters":[{"$ref":"#\/components\/parameters\/WebhookId"}],"responses":{"200":{"$ref":"#\/components\/responses\/SuccessNull"},"404":{"$ref":"#\/components\/responses\/WebhookNotFound"},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"}}}},"\/webhooks\/{webhook}\/test":{"post":{"tags":["Webhooks"],"summary":"Send a test delivery","description":"Sends a synthetic test payload to the webhook URL and returns the outcome","operationId":"testWebhook","parameters":[{"$ref":"#\/components\/parameters\/WebhookId"}],"responses":{"200":{"description":"Test delivery performed","content":{"application\/json":{"schema":{"type":"object","properties":{"result":{"type":"boolean","example":true},"data":{"$ref":"#\/components\/schemas\/WebhookTestResult"}}},"example":{"result":true,"data":{"status_code":200,"response_time_ms":123,"success":true}}}}},"404":{"$ref":"#\/components\/responses\/WebhookNotFound"},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"}}}},"\/webhooks\/{webhook}\/logs":{"get":{"tags":["Webhooks"],"summary":"Get webhook delivery logs","description":"Returns a cursor-paginated list of delivery attempts for the webhook, newest first.\nPass the returned `next_cursor` as the `cursor` query parameter to fetch the next page;\na null `next_cursor` means there are no more pages.\n","operationId":"getWebhookLogs","parameters":[{"$ref":"#\/components\/parameters\/WebhookId"},{"name":"limit","in":"query","description":"Page size","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":20,"example":20}},{"name":"cursor","in":"query","description":"Opaque pagination cursor returned as next_cursor by a previous request","required":false,"schema":{"type":["string","null"]}}],"responses":{"200":{"description":"Successful response","content":{"application\/json":{"schema":{"type":"object","properties":{"result":{"type":"boolean","example":true},"data":{"$ref":"#\/components\/schemas\/WebhookLogPage"}}}}}},"404":{"$ref":"#\/components\/responses\/WebhookNotFound"},"422":{"description":"Validation error","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"},"examples":{"invalidLimit":{"summary":"Param limit unsupported","value":{"result":false,"data":null,"error":"Param limit must be an integer between 1 and 100","code":4431}},"cursorType":{"summary":"Param cursor must be a string","value":{"result":false,"data":null,"error":"Param cursor must be a string","code":4432}},"invalidCursor":{"summary":"Param cursor invalid","value":{"result":false,"data":null,"error":"Param cursor is invalid or belongs to another webhook","code":4433}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"}}}},"\/webhooks\/{webhook}\/logs\/retry":{"post":{"tags":["Webhooks"],"summary":"Retry a delivery","description":"Re-sends a single previously logged delivery. The log entry is identified by `log_id`\n(the `id` field of a delivery log entry). It is passed in the body because the reverse\nproxy decodes the \"#\" in the id and would truncate it in the URI.\n","operationId":"retryWebhookDelivery","parameters":[{"$ref":"#\/components\/parameters\/WebhookId"}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["log_id"],"properties":{"log_id":{"type":"string","maxLength":255,"description":"Delivery log entry id (created_at_id)","example":"2026-06-09T12:00:00.000Z#cc290033-22bc-c302-315b-07073e0f6a73"}}}}}},"responses":{"200":{"$ref":"#\/components\/responses\/SuccessNull"},"404":{"description":"Webhook or log entry not found","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"},"examples":{"webhookNotFound":{"summary":"Webhook not found","value":{"result":false,"data":null,"error":"Webhook not found","code":4401}},"logNotFound":{"summary":"Log entry not found","value":{"result":false,"data":null,"error":"Log entry not found","code":4427}}}}}},"422":{"description":"Validation error","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"},"examples":{"requireLogId":{"summary":"Param log_id required","value":{"result":false,"data":null,"error":"Param log_id is required","code":4429}},"invalidLogId":{"summary":"Param log_id unsupported","value":{"result":false,"data":null,"error":"Param log_id must be a string up to 255 characters","code":4430}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"}}}},"\/webhooks\/{webhook}\/events\/{action}":{"post":{"tags":["Webhooks"],"summary":"Add an event to a webhook","description":"Subscribes the webhook to an active action. Optionally scopes the event to specific\naddress books via `address_book_id`. Returns the updated webhook.\n","operationId":"addWebhookEvent","parameters":[{"$ref":"#\/components\/parameters\/WebhookId"},{"$ref":"#\/components\/parameters\/ActionId"}],"requestBody":{"required":false,"content":{"application\/json":{"schema":{"type":"object","properties":{"address_book_id":{"type":"array","items":{"type":"integer","minimum":1},"description":"Optional address book ids the event is limited to"}}},"example":{"address_book_id":[1113605]}}}},"responses":{"200":{"description":"Event added; updated webhook returned","content":{"application\/json":{"schema":{"type":"object","properties":{"result":{"type":"boolean","example":true},"data":{"$ref":"#\/components\/schemas\/Webhook"}}}}}},"404":{"description":"Webhook or action not found","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"},"examples":{"webhookNotFound":{"summary":"Webhook not found","value":{"result":false,"data":null,"error":"Webhook not found","code":4401}},"actionNotFound":{"summary":"Action not found","value":{"result":false,"data":null,"error":"Action not found","code":4303}}}}}},"422":{"description":"Validation error","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"},"examples":{"invalidAddressBookId":{"summary":"Param address_book_id unsupported","value":{"result":false,"data":null,"error":"Param address_book_id must be an array of positive integers","code":4410}},"eventDuplicate":{"summary":"Webhook event duplicate","value":{"result":false,"data":null,"error":"Webhook event duplicate","code":4411}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"}}},"delete":{"tags":["Webhooks"],"summary":"Remove an event from a webhook","description":"Unsubscribes the webhook from an action","operationId":"removeWebhookEvent","parameters":[{"$ref":"#\/components\/parameters\/WebhookId"},{"$ref":"#\/components\/parameters\/ActionId"}],"responses":{"200":{"$ref":"#\/components\/responses\/SuccessNull"},"404":{"description":"Webhook or webhook event not found","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"},"examples":{"webhookNotFound":{"summary":"Webhook not found","value":{"result":false,"data":null,"error":"Webhook not found","code":4401}},"eventNotFound":{"summary":"Webhook event not found","value":{"result":false,"data":null,"error":"Webhook event not found","code":4428}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"}}}}},"components":{"parameters":{"WebhookId":{"name":"webhook","in":"path","required":true,"description":"Webhook ID","schema":{"type":"integer","example":15}},"ActionId":{"name":"action","in":"path","required":true,"description":"Action ID","schema":{"type":"integer","example":11}}},"schemas":{"Webhook":{"type":"object","properties":{"id":{"type":"integer","example":15},"user_id":{"type":"integer","example":905},"name":{"type":["string","null"],"description":"Optional human-readable name","example":"My integration"},"url":{"type":"string","format":"uri","description":"HTTPS endpoint deliveries are sent to","example":"https:\/\/example.com\/webhook-endpoint"},"secret_key":{"type":"string","description":"Secret used to sign deliveries (verify the signature header on your side)","example":"b1946ac92492d2347c6235b4d2611184"},"status":{"type":"integer","enum":[0,1,2],"description":"1 = ACTIVE, 0 = INACTIVE, 2 = DISABLED_AUTO (auto-disabled by the circuit breaker)","example":1},"headers":{"type":"array","description":"Custom headers sent with every delivery. Values are always masked in responses.","items":{"$ref":"#\/components\/schemas\/WebhookHeaderMasked"}},"events":{"type":"array","items":{"$ref":"#\/components\/schemas\/WebhookEventItem"}},"created_at":{"type":"string","format":"date-time","example":"2025-11-11T15:43:20.000000Z"},"updated_at":{"type":"string","format":"date-time","example":"2025-11-11T15:43:20.000000Z"}}},"WebhookEventItem":{"type":"object","description":"An action the webhook is subscribed to","properties":{"id":{"type":"integer","description":"Action id","example":12},"scope":{"type":"string","example":"email_service"},"event":{"type":"string","example":"tag_linked"},"address_book_id":{"type":"array","description":"Address book ids this event is limited to (empty = all)","items":{"type":"integer"},"example":[1113605]}}},"WebhookHeaderMasked":{"type":"object","properties":{"name":{"type":"string","example":"X-Custom-Token"},"value":{"type":"string","description":"Masked value; the real value never leaves the service. The first 2 and last 3\ncharacters of the secret are kept, the rest is replaced with \"\u2022\u2022\u2022\u2022\u2022\u2022\". An auth\nscheme prefix (e.g. \"Bearer \") stays readable; a secret of 5 characters or fewer\nis hidden entirely (\"\u2022\u2022\u2022\u2022\u2022\u2022\").\n","example":"Bearer ab\u2022\u2022\u2022\u2022\u2022\u20227f9"}}},"WebhookHeaderInput":{"type":"object","required":["name"],"properties":{"name":{"type":"string","description":"1-128 characters of an RFC 7230 token","example":"X-Custom-Token"},"value":{"type":["string","null"],"description":"1-1024 printable ASCII characters. On update, null keeps the value already stored\nfor this header (the only way to leave a secret untouched without reading it back).\n","example":"s3cr3t"}}},"WebhookCreateRequest":{"type":"object","required":["url","events"],"properties":{"name":{"type":["string","null"],"maxLength":255,"example":"My integration"},"url":{"type":"string","format":"uri","description":"Must be a public HTTPS URL","example":"https:\/\/example.com\/webhook-endpoint"},"events":{"type":"array","minItems":1,"description":"Active action ids to subscribe to","items":{"type":"integer"},"example":[11,12]},"status":{"type":"integer","enum":[0,1],"default":1,"description":"1 = ACTIVE, 0 = INACTIVE","example":1},"address_book_id":{"type":"array","description":"Optional address book ids applied to every event","items":{"type":"integer","minimum":1},"example":[1113605]},"headers":{"type":"array","maxItems":10,"description":"Up to 10 custom headers, 8192 bytes total","items":{"$ref":"#\/components\/schemas\/WebhookHeaderInput"}}}},"WebhookUpdateRequest":{"type":"object","description":"All fields optional; only fields present are changed","properties":{"name":{"type":["string","null"],"maxLength":255,"description":"null or empty clears the stored name","example":"Renamed integration"},"url":{"type":"string","format":"uri","example":"https:\/\/example.com\/new-webhook-endpoint"},"events":{"type":"array","minItems":1,"items":{"type":"integer"},"example":[11]},"address_book_id":{"type":"array","items":{"type":"integer","minimum":1},"example":[1113605]},"headers":{"type":"array","maxItems":10,"items":{"$ref":"#\/components\/schemas\/WebhookHeaderInput"}}}},"WebhookDeliveryLog":{"type":"object","properties":{"id":{"type":"string","description":"Log entry id (created_at_id); pass as log_id to retry","example":"2026-06-09T12:00:00.000Z#cc290033-22bc-c302-315b-07073e0f6a73"},"scope":{"type":"string","description":"Databus scope the delivery originated from (empty for pre-scope entries)","example":"email_service"},"event_type":{"type":"string","example":"tag_linked"},"response_code":{"type":"integer","description":"HTTP status code; 0 means no attempt or a network error","example":200},"response_time_ms":{"type":"integer","example":123},"attempt_number":{"type":"integer","description":"1-based attempt index","example":1},"dropped_by_circuit":{"type":"boolean","description":"true when the circuit breaker prevented the HTTP attempt","example":false},"created_at":{"type":"string","format":"date-time","example":"2026-06-09T12:00:00.000Z"},"request_body":{"type":["string","null"]},"response_body":{"type":["string","null"]},"request_headers":{"type":"object","additionalProperties":true,"description":"Headers sent with the request"}}},"WebhookLogPage":{"type":"object","description":"One page of delivery logs with a cursor to the next page","properties":{"items":{"type":"array","items":{"$ref":"#\/components\/schemas\/WebhookDeliveryLog"}},"next_cursor":{"type":["string","null"],"description":"Cursor for the next page; null when there are no more pages","example":"eyJ3ZWJob29rX2lkIjp7Ik4iOiIxNSJ9fQ=="}}},"WebhookTestResult":{"type":"object","properties":{"status_code":{"type":"integer","description":"HTTP status returned by the endpoint (0 on network error)","example":200},"response_time_ms":{"type":"integer","example":123},"success":{"type":"boolean","description":"true when the status is 2xx","example":true}}},"Error":{"type":"object","properties":{"result":{"type":"boolean","example":false},"data":{"type":["object","null"],"example":null},"error":{"type":"string","description":"Error description","example":"Some error message"},"code":{"type":"integer","description":"Unique error code","example":12}}}},"responses":{"SuccessNull":{"description":"Operation successful; no payload","content":{"application\/json":{"schema":{"type":"object","properties":{"result":{"type":"boolean","example":true},"data":{"type":["object","null"],"example":null}}},"example":{"result":true,"data":null}}}},"Unauthorized":{"description":"Unauthorized access","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"},"example":{"result":false,"data":null,"error":"Unauthorized action!","code":401}}}},"Forbidden":{"description":"Access denied by RBAC","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"},"example":{"result":false,"data":null,"error":"Access denied by RBAC","code":4426}}}},"WebhookNotFound":{"description":"Webhook not found response","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"},"example":{"result":false,"data":null,"error":"Webhook not found","code":4401}}}}},"securitySchemes":{"apiKey":{"type":"apiKey","in":"header","name":"Authorization"},"oauth2":{"type":"oauth2","flows":{"clientCredentials":{"tokenUrl":"https:\/\/api.sendpulse.com\/oauth\/access_token","scopes":[]}}}}},"security":[{"oauth2":[]},{"apiKey":[]}]}