API and webhooks
Issue a workspace token, list and reply to conversations over HTTPS, and verify signed events when a thread is handed off, resolved, or rated.
Where it lives
API in the workspace sidebar — /workspaces/:id/api. It is owner-only, like Site keys and Team. You need an active subscription to create or revoke a token or register a webhook. The page is visible either way.
Create a token
Name the token and choose the scopes it may use. Doorwick shows the plaintext value once — dw_ followed by hex. Copy it into your secret manager. After that, only a SHA-256 digest is stored, so it cannot be recovered from the dashboard.
- conversations:read
- List conversations and read a thread, including visitor-visible messages.
- conversations:write
- Post an operator reply. Visitors see it in the widget.
- conversations:resolve
- Resolve a conversation or reopen it.
- Content synchronization
- A preset of eight narrow scopes for managed knowledge, AI readiness, the system prompt, visitor quick actions, previews, and run history.
Send it as Authorization: Bearer dw_… to https://chat.doorwick.com/v1. Revoke a token from the same page when you rotate it.
Validate a newly configured integration with GET /v1/token. It returns the token name and scopes, its workspace, and supported content/webhook schema versions without returning any secret. The machine-readable contracts are published as OpenAPI and a manifest JSON Schema.
Synchronize public content
Managed Content Sync coordinates versioned knowledge sources, the system prompt, and visitor quick actions. It previews every action before applying, rejects stale previews, and never treats omission as permission to retire content by default. Read the Managed Content Sync guide.
- POST /v1/ai_readiness_probes
- Tests harmless chat and embedding calls and returns safe, actionable provider codes.
- GET /v1/knowledge_readiness
- Reports the strict visitor-AI gate, indexed counts, provider health, latest release, retry timing, and limits.
- POST /v1/content_sync_runs/:id/retry_attempts
- Retries failed staged items only; it never rewrites already verified items.
- POST /v1/knowledge_reindexings
- Queues a bounded whole-collection or failed-only recovery.
List conversations
GET /v1/conversations returns the workspace inbox, newest activity first. Filter with status=open, pending_human, or resolved. Page with cursor and limit (default 20, max 50).
curl -s https://chat.doorwick.com/v1/conversations?status=pending_human \
-H "Authorization: Bearer $DOORWICK_API_TOKEN"Read a thread
GET /v1/conversations/:id returns the contact, status, and visitor-visible messages. Internal operator notes are not included.
curl -s https://chat.doorwick.com/v1/conversations/42 \
-H "Authorization: Bearer $DOORWICK_API_TOKEN"Reply as an operator
POST /v1/conversations/:id/messages with { "body": "…" } posts a reply the visitor can see — the same as sending from the inbox. Needs conversations:write. A reply to a resolved thread reopens it.
curl -s https://chat.doorwick.com/v1/conversations/42/messages \
-H "Authorization: Bearer $DOORWICK_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"body":"We are looking into this and will update you shortly."}'Resolve and reopen
Both need conversations:resolve.
- POST /v1/conversations/:id/resolve
- Marks the thread resolved and tells the widget so it can offer a rating.
- POST /v1/conversations/:id/reopen
- Opens a resolved thread again.
Errors
Requests without a token, or with an unknown token, return 401. A valid token missing the scope for that action returns 403. An id from another workspace returns 404 — Doorwick does not confirm that the conversation exists.
Error bodies contain a stable code plus a human-readable error. A rate-limited request returns 429 and Retry-After. List endpoints use an opaque cursor, return next_cursor, and accept limit up to 50. Knowledge inventory can filter by management mode, collection, refresh state, and retirement; use include_content=false for metadata-only pages. Sync history can filter by collection, release, and status.
Webhooks
Register an HTTPS URL and the events you want. Doorwick shows the signing secret once. The events are:
- conversation.escalated
- Status became
pending_human. - conversation.resolved
- Status became
resolved. - conversation.rated
- A CSAT score was recorded.
- ai.no_answer
- Knowledge retrieval found nothing relevant for a visitor question.
- content_sync.succeeded
- A managed release completed successfully.
- content_sync.partially_failed
- Only optional managed sources failed.
- content_sync.failed
- A required source or deterministic verification failed.
A delivery looks like:
{
"id": "4d3a20b3-610f-4ed0-b599-45cf131b5b88",
"delivery_id": "6dc84df3-1c1d-44e4-a1fc-8f6dcadf3401",
"schema_version": 1,
"event": "conversation.escalated",
"sent_at": "2026-08-21T19:00:00Z",
"data": {
"conversation": {
"id": 42,
"status": "pending_human",
"handler": "human",
"contact": { "id": 7, "email": "sam@example.com", "name": "Sam" }
}
}
}Verify the signature
Every delivery is HMAC-signed with the endpoint secret. Reject timestamps older than about five minutes so a captured request cannot be replayed.
- X-Doorwick-Timestamp / X-Webhook-Timestamp
- Unix seconds
- X-Doorwick-Event-ID
- Stable event identifier; use it to deduplicate side effects.
- X-Doorwick-Delivery-ID
- Unique identifier for this endpoint delivery.
- X-Webhook-Signature-V2
- hex
HMAC-SHA256(secret, "{timestamp}.{body}") - X-Doorwick-Signature
- the same digest, prefixed
sha256= - X-Doorwick-Event
- the event name
require "openssl"
def doorwick_signature_valid?(secret, timestamp, body, signature)
expected = OpenSSL::HMAC.hexdigest("SHA256", secret, [timestamp, body].join("."))
provided = signature.to_s.delete_prefix("sha256=")
OpenSSL.fixed_length_secure_compare(expected, provided)
endDoorwick retries network errors, 408, 425, 429, and 5xx responses up to five attempts and honors a bounded Retry-After. Other 4xx responses are terminal. The API page shows durable attempt evidence and allows an owner to replay while the separately encrypted payload is retained for seven days.