Chatqus CRM API

Outgoing Webhooks

Server

Outgoing webhook management (supervisor/admin only). Delivery is at-least-once: events are captured durably (Redis stream) and retried with exponential backoff, so the same event may be POSTed more than once (e.g. after a transient receiver/network failure or a dispatcher restart). Receivers must be idempotent — deduplicate on the event's natural identifiers in the JSON body (timestamp plus the relevant id under data, e.g. data.message.id / data.conversation_id) together with the X-Omnistream-Event header, and verify the X-Omnistream-Signature HMAC. Do not assume exactly-once. Deliveries that exhaust all retry attempts (default 8, capped exponential backoff) move to a dead-letter queue (status = dead_letter) and can be replayed. During a secret-rotation overlap window each delivery carries two signatures — X-Omnistream-Signature (new secret) and X-Omnistream-Signature-Previous (old secret); accept the delivery if EITHER header matches the secret you have stored. Full runbook: docs/webhook-reliability.md.


List outgoing webhooks

GET
https://api-chat.misindo.id
/api/outgoing-webhooks

Supervisor or admin only.

List outgoing webhooks › Responses

Outgoing webhooks

id
​string · uuid · required
name
​string · required
url
​string · required
events
​required

JSON array of subscribed event type strings

is_active
​boolean · required
consecutive_failures
​integer · required
created_at
​string · date-time · required
updated_at
​string · date-time · required
secret
​string · writeOnly

HMAC signing secret. Write-only — never returned in responses. The staged rotation secret (secret_next) is likewise never returned; a pending rotation is only visible via secret_rotated_at.

secret_rotated_at
​string · date-time

When the current secret-rotation overlap window started. Null when no rotation is in progress (cleared on complete, cancel, or the 24-hour auto-promote).

created_by
​string · uuid
last_triggered_at
​string · date-time
last_success_at
​string · date-time

Create an outgoing webhook

POST
https://api-chat.misindo.id
/api/outgoing-webhooks

Supervisor or admin only.

Create an outgoing webhook › Request Body

name
​string · minLength: 1 · required
url
​string · required

Must start with http:// or https://

secret
​string
events
​string[]

Valid types: message.received, message.sent, message.status, conversation.created, conversation.resolved, conversation.assigned, whatsapp.flow.completed, contact.created

Create an outgoing webhook › Responses

Webhook created

id
​string · uuid · required
name
​string · required
url
​string · required
events
​required

JSON array of subscribed event type strings

is_active
​boolean · required
consecutive_failures
​integer · required
created_at
​string · date-time · required
updated_at
​string · date-time · required
secret
​string · writeOnly

HMAC signing secret. Write-only — never returned in responses. The staged rotation secret (secret_next) is likewise never returned; a pending rotation is only visible via secret_rotated_at.

secret_rotated_at
​string · date-time

When the current secret-rotation overlap window started. Null when no rotation is in progress (cleared on complete, cancel, or the 24-hour auto-promote).

created_by
​string · uuid
last_triggered_at
​string · date-time
last_success_at
​string · date-time

List available webhook event types

GET
https://api-chat.misindo.id
/api/outgoing-webhooks/events

Supervisor or admin only.

List available webhook event types › Responses

200

Event type strings

​string[]

Aggregated delivery statistics

GET
https://api-chat.misindo.id
/api/outgoing-webhooks/deliveries/stats

Supervisor or admin only. Per-status delivery counts (including dead-lettered rows) plus average response time, over an optional created_at date range.

Aggregated delivery statistics › query Parameters

from
​string · date-time
to
​string · date-time

Aggregated delivery statistics › Responses

Delivery statistics

total
​integer · required
success
​integer · required
failed
​integer · required

Failed but still retryable (attempt < max_attempts)

pending
​integer · required
dead_letter
​integer · required

Terminally failed deliveries awaiting replay or 30-day cleanup

avg_response_time_ms
​number

Average milliseconds between created_at and completed_at


Bulk-replay deliveries by id

POST
https://api-chat.misindo.id
/api/outgoing-webhooks/deliveries/replay

Supervisor or admin only. Resets each failed/dead-lettered delivery in place — status back to pending, attempt counter zeroed, response fields cleared — so the scheduler re-sends it with the original payload. Ids that are unknown or not replayable are skipped and excluded from replayed.

Bulk-replay deliveries by id › Request Body

delivery_ids
​string[] · minItems: 1 · maxItems: 500 · required

Deliveries to replay; only failed/dead_letter rows are reset

Bulk-replay deliveries by id › Responses

Replay summary

replayed
​integer

Rows actually reset to pending

requested
​integer

Ids received in the request


Replay all dead-lettered deliveries

POST
https://api-chat.misindo.id
/api/outgoing-webhooks/deliveries/replay-failed

Supervisor or admin only. Resets every dead_letter delivery in place for re-sending. The body is optional — omit it (or send {}) to replay across all webhooks, or pass webhook_id to scope the replay to a single webhook.

Replay all dead-lettered deliveries › Request Body optional

webhook_id
​string · uuid

Restrict the replay to this webhook's deliveries

Replay all dead-lettered deliveries › Responses

Replay summary

replayed
​integer

Replay a single delivery

POST
https://api-chat.misindo.id
/api/outgoing-webhooks/deliveries/{delivery_id}/replay

Supervisor or admin only. Resets one failed or dead-lettered delivery in place (status back to pending, attempt counter zeroed, response fields cleared); the scheduler re-sends it with the original payload within ~30 seconds.

Replay a single delivery › path Parameters

delivery_id
​string · uuid · required

Replay a single delivery › Responses

Delivery queued for replay

delivery_id
​string · uuid · required
status
​string · required

Always "queued" on success

message
​string · required

Delete an outgoing webhook

DELETE
https://api-chat.misindo.id
/api/outgoing-webhooks/{id}

Supervisor or admin only.

Delete an outgoing webhook › path Parameters

id
​string · uuid · required

Delete an outgoing webhook › Responses

Webhook deleted

message
​string
id
​string · uuid

Update an outgoing webhook

PATCH
https://api-chat.misindo.id
/api/outgoing-webhooks/{id}

Supervisor or admin only.

Update an outgoing webhook › path Parameters

id
​string · uuid · required

Update an outgoing webhook › Request Body

name
​string
url
​string
secret
​string
events
​string[]
is_active
​boolean

Update an outgoing webhook › Responses

Webhook updated

id
​string · uuid · required
name
​string · required
url
​string · required
events
​required

JSON array of subscribed event type strings

is_active
​boolean · required
consecutive_failures
​integer · required
created_at
​string · date-time · required
updated_at
​string · date-time · required
secret
​string · writeOnly

HMAC signing secret. Write-only — never returned in responses. The staged rotation secret (secret_next) is likewise never returned; a pending rotation is only visible via secret_rotated_at.

secret_rotated_at
​string · date-time

When the current secret-rotation overlap window started. Null when no rotation is in progress (cleared on complete, cancel, or the 24-hour auto-promote).

created_by
​string · uuid
last_triggered_at
​string · date-time
last_success_at
​string · date-time

List deliveries for a webhook

GET
https://api-chat.misindo.id
/api/outgoing-webhooks/{id}/deliveries

Supervisor or admin only. Paginated, newest first.

List deliveries for a webhook › path Parameters

id
​string · uuid · required

List deliveries for a webhook › query Parameters

page
​integer
Default: 1
per_page
​integer · max: 100
Default: 50

List deliveries for a webhook › Responses

200

Webhook deliveries

id
​string · uuid · required
webhook_id
​string · uuid · required
event_type
​string · required
​WebhookPayload · required

The body of one webhook delivery. Which variant arrives is determined by event_type: conversation and message events use WebhookEventPayload, automation events use WebhookAutomationPayload, and the "Send Test" button uses WebhookTestPayload. Note that data.message is an object on conversation events but a plain string on the test event — branch on event_type before reading it.

status
​string · enum · required

pending = queued, awaiting the next scheduler tick; sending = claimed by a dispatcher worker (15-minute lease, reclaimed if the lease expires); success = delivered (HTTP 2xx); failed = last attempt failed but retries remain; dead_letter = terminal (attempts exhausted, webhook missing/inactive, or URL blocked) — never retried automatically, only a replay re-queues it.

Enum values:
pending
sending
success
failed
dead_letter
attempt
​integer · required
max_attempts
​integer · required

Delivery attempts before dead-lettering (default 8)

created_at
​string · date-time · required
http_status
​integer
response_body
​string
error_message
​string
next_retry_at
​string · date-time
completed_at
​string · date-time

Send a test event to the webhook

POST
https://api-chat.misindo.id
/api/outgoing-webhooks/{id}/test

Supervisor or admin only. Sends a test payload and returns the response.

Send a test event to the webhook › path Parameters

id
​string · uuid · required

Send a test event to the webhook › Responses

Test result

success
​boolean
http_status
​integer
response_body
​string
error
​string

Start a signing-secret rotation

POST
https://api-chat.misindo.id
/api/outgoing-webhooks/{id}/rotate-secret

Supervisor or admin only. Stages a new HMAC secret and opens a 24-hour overlap window: deliveries are signed with the NEW secret in X-Omnistream-Signature and with the OLD secret in X-Omnistream-Signature-Previous, so receivers can switch secrets without dropping deliveries. Complete (or cancel) the rotation explicitly, or it auto-promotes after 24 hours. The new secret is returned once in this response and never again.

Start a signing-secret rotation › path Parameters

id
​string · uuid · required

Start a signing-secret rotation › Request Body optional

secret
​string · minLength: 16 · maxLength: 255

Optional custom secret (16–255 chars after trimming). Omit to have the server generate a 64-character lowercase-hex secret.

Start a signing-secret rotation › Responses

Rotation started

id
​string · uuid · required
secret
​string · required

The new signing secret — shown once, never returned again

rotated_at
​string · date-time · required

Start of the dual-signature overlap window

overlap
​string · required

Human-readable note that the previous secret keeps working for up to 24 hours or until the rotation is completed


Complete a pending secret rotation

POST
https://api-chat.misindo.id
/api/outgoing-webhooks/{id}/rotate-secret/complete

Supervisor or admin only. Promotes the staged secret to the active signing secret and ends the overlap window — the old secret stops matching immediately.

Complete a pending secret rotation › path Parameters

id
​string · uuid · required

Complete a pending secret rotation › Responses

Rotation completed

id
​string · uuid · required
name
​string · required
url
​string · required
events
​required

JSON array of subscribed event type strings

is_active
​boolean · required
consecutive_failures
​integer · required
created_at
​string · date-time · required
updated_at
​string · date-time · required
secret
​string · writeOnly

HMAC signing secret. Write-only — never returned in responses. The staged rotation secret (secret_next) is likewise never returned; a pending rotation is only visible via secret_rotated_at.

secret_rotated_at
​string · date-time

When the current secret-rotation overlap window started. Null when no rotation is in progress (cleared on complete, cancel, or the 24-hour auto-promote).

created_by
​string · uuid
last_triggered_at
​string · date-time
last_success_at
​string · date-time

Cancel a pending secret rotation

POST
https://api-chat.misindo.id
/api/outgoing-webhooks/{id}/rotate-secret/cancel

Supervisor or admin only. Discards the staged secret and keeps the OLD secret active; deliveries return to a single X-Omnistream-Signature header.

Cancel a pending secret rotation › path Parameters

id
​string · uuid · required

Cancel a pending secret rotation › Responses

Rotation cancelled

id
​string · uuid · required
name
​string · required
url
​string · required
events
​required

JSON array of subscribed event type strings

is_active
​boolean · required
consecutive_failures
​integer · required
created_at
​string · date-time · required
updated_at
​string · date-time · required
secret
​string · writeOnly

HMAC signing secret. Write-only — never returned in responses. The staged rotation secret (secret_next) is likewise never returned; a pending rotation is only visible via secret_rotated_at.

secret_rotated_at
​string · date-time

When the current secret-rotation overlap window started. Null when no rotation is in progress (cleared on complete, cancel, or the 24-hour auto-promote).

created_by
​string · uuid
last_triggered_at
​string · date-time
last_success_at
​string · date-time