BuckhyDeveloper Platform

Reference

Engage API

Public endpoints under /v1/engage used by AI Chat, Managed Forms and Support Desk — requests, responses and errors — plus the console management endpoints.

Public endpoints

Base URL https://api.buckhy.com. Every public endpoint except /sdk.js requires X-Api-Key: bk_live_… and a request Origin that is allow-listed for the site (requests without an Origin header — servers and mobile apps — are accepted).

Method Path App Purpose
GET /v1/engage/sdk.js all The embeddable loader. No key.
GET /v1/engage/config all Health, module flags and branding. Drives show/hide.
POST /v1/engage/chat AI Chat One visitor turn.
GET /v1/engage/conversations/:id?visitorToken=… AI Chat A visitor reads their own thread.
POST /v1/engage/forms/:form Managed Forms Store a managed form submission.
POST /v1/engage/support Support Desk Create a support ticket.

Common errors from key and origin checks:

Status Message
401 missing api key · invalid or revoked engage key
403 engage site not found · engage site is disabled · origin not allowed for this site
403 MODULE_DISABLED — the module for that endpoint is off
429 Rate limit: 120 requests / 15 minutes per key
503 key verification unavailable — retry with backoff

GET /config

{
  "ok": true,
  "name": "Northbeam Outfitters",
  "assistantName": "Trail Guide",
  "modules": { "chat": true, "forms": true, "support": true },
  "identityMode": "anonymous",
  "branding": { "launcherLabel": "Ask the trail crew", "accent": "#1457d9", "greeting": "Planning a trek?" }
}

Cached by the SDK and CDNs for 5 minutes (Cache-Control: public, max-age=300).

POST /chat

Rate limit: 12 messages / minute per key and visitor IP.

Request

Property Type Required Notes
message string yes ≤ 2,000 characters
visitorToken string no From a previous response; resumes the thread
visitor { id?, name?, email? } no email is required when the site's identity mode is email
page, pageTitle string no Where the visitor is; shown in the console

Response

{
  "success": true,
  "visitorToken": "evt_…",
  "conversationId": "6a9…",
  "answer": "You can return used boots within 30 days…",
  "citations": [{ "slug": "returns", "title": "30-day trail returns" }],
  "escalate": false,
  "status": "ai"
}

While a person holds the thread the reply is { "success": true, "queued": true, "status": "agent", … } and the assistant stays silent. When escalate is true the answer points to the support form and a chat.escalated webhook is delivered.

Status Code Meaning
400 — message is required
400 IDENTITY_REQUIRED Site requires an email before chatting
403 MODULE_DISABLED Chat is off
503 ASSISTANT_UNAVAILABLE The model could not answer; the visitor's message is kept

GET /conversations/:id?visitorToken=… returns { status, messages[] { role, content, citations, sentAt } } for the visitor's own thread; 404 when the token does not match.

POST /forms/:form

:form is the form label (≤ 40 characters, default contact).

Property Type Required Notes
fields object yes Up to 24 string fields, 2,000 characters each. website, url and homepage are treated as honeypots and dropped.
page string no ≤ 300

The ticket's contact is read from fields.name, fields.email and fields.phone; its subject from fields.subject; its message from fields.message or fields.notes.

201 { "success": true, "id": "ENG-F-5C213AA2", "successMessage": "Thank you." }, or 200 with "duplicate": true on replay. successMessage is present when a configured form policy applies. Missing configured required fields or an unconfigured form ID in strict mode returns 400. Disabled integrations return 403. 400 fields are required is returned when nothing survives sanitisation.

POST /support

Property Type Required Notes
name string yes ≤ 120
email string yes Valid address, ≤ 160
message string yes ≤ 5,000
phone string no ≤ 30
category string no ≤ 40; default general
subject string no ≤ 200; defaults to the first 80 characters of the message
page string no ≤ 300
conversationId string no Links the ticket to a chat thread

201 { "success": true, "ticketId": "ENG-T-7F3A9C21" }, or 200 with "duplicate": true on an idempotent replay. 400 with name and a valid email are required or message is required.

Idempotency

/chat is naturally idempotent per message. /support and /forms/:form accept an Idempotency-Key header (8–100 characters, A–Z a–z 0–9 _ -):

  • Same key, same content → 200 with the original id and duplicate: true.
  • Same key, different content → 409.
  • Malformed keys are ignored, not rejected.

The SDK generates a new key per submission attempt and reuses it on retry; do the same in your own clients.

Console endpoints

The developer console manages sites through /api/engage/sites, authenticated with the portal's service credentials (X-Portal-Key and X-Identity-Sub). Site owners only ever see their own sites. Listed for completeness; use the console UI.

Method Path Purpose
GET / POST / List / create sites
PATCH /:id Name, origins, modules, identity mode, answer mode, branding, webhook, status
GET / PUT /:id/knowledge Read / replace the context and articles
POST /:id/keys Issue a key, revoking the previous one
GET /:id/stats Ticket and conversation counts, knowledge size
GET /:id/tickets?status&source&page Ticket inbox
POST /:id/tickets/:ticketId/reply Agent reply { message, resolve? } → status in_progress or resolved
GET /:id/conversations?status&page Chat transcripts
POST /:id/conversations/:cid/reply Take over { message }
POST /:id/conversations/:cid/release Hand back to the assistant
POST /:id/conversations/:cid/close Close the thread
POST /:id/webhook/test Send one signed webhook.test event