HelpStackDocs

Integrations

API Reference

REST API for the HelpStack dashboard, widget, and webhooks.

Quick facts#

Base pathEndpoints live under https://helpstack.eu/api/… — a path prefix, not a reachable URL
Auth (dashboard API)NextAuth session cookie (logged-in user)
Auth (widget API)None (public, rate-limited)
Auth (webhooks)Verify-token handshake + HMAC-SHA256 signature
Content-Typeapplication/json (file uploads use multipart/form-data)
TenancyEvery dashboard request is scoped to the session user's organization

Expect a 404 on /api itself, and 401 on authenticated endpoints. There is no route at the bare https://helpstack.eu/api — it returns 404 by design, because the API is a set of sub-paths (/api/conversations, /api/channels, …), not a browsable root. Opening a real endpoint like /api/conversations in a browser returns 401 (no session cookie), which confirms it exists and is auth-protected. Neither response is a bug.

Authentication model — read this first#

There is currently no public API-key or bearer-token system for third-party callers. Do not look for an "API key" — none exists. The dashboard/internal API is authenticated with the NextAuth session cookie of a logged-in user, and every request is automatically scoped to that user's organization by middleware (withOrganization / withAdmin / withAgent). These endpoints are consumed by the HelpStack dashboard UI.

To call dashboard endpoints from outside the browser you must replay an authenticated session cookie. If you need machine-to-machine access, the supported public surfaces are:

  • Widget endpoints — public, IP/visitor rate-limited (see Widget Embed).
  • Webhook endpoints — public, verified by token + HMAC signature (see Webhooks).

Treat anything requiring a session cookie as "verify against your deployment" for programmatic use.

Response envelope#

All API routes return a standard envelope.

Success

{ "success": true, "data": { } }

Error

{
  "success": false,
  "error": {
    "message": "Human-readable message",
    "code": "OPTIONAL_CODE",
    "fields": { "fieldName": ["error 1"] }
  }
}

code and fields are optional. fields is populated for validation errors (Zod) with per-field messages.

Error codes & HTTP status#

Errors are produced by typed error classes and a central handler. High-level mapping:

HTTPWhenExample code
400Invalid input / validation failureVALIDATION_ERROR
401Missing or expired auth
402Insufficient tokens to perform the actionINSUFFICIENT_TOKENS
403Insufficient role/permission
404Resource not found
409Duplicate/conflict
429Rate limit hit
502Third-party API failure
500Unexpected/internal error (message is masked)

Zod validation failures return 400 with code: "VALIDATION_ERROR" and a fields object. Unexpected errors return 500 with a generic message ("An unexpected error occurred"); the real detail is logged server-side only.

Endpoint catalog#

Roles: an endpoint marked ADMIN requires admin (withAdmin), AGENT requires agent-or-higher (withAgent), Session requires any authenticated org member (withOrganization).

Channels

MethodPathPurposeAuth
GET/api/channelsList channelsSession
POST/api/channelsCreate channelADMIN
GET/api/channels/[id]Get one channelSession
PATCH/api/channels/[id]Update channelADMIN
DELETE/api/channels/[id]Delete channelADMIN
GET/api/channels/[id]/widget-scriptGet embed script for a WEBSITE_CHAT channelSession
GET/api/channels/[id]/widget-configGet widget appearance configSession
GET/POST/api/channels/[id]/agent-toolsList/attach channel-scoped agent toolsSession

Create channelPOST /api/channels (verified body, createChannelSchema):

{
  "type": "WEBSITE_CHAT",
  "name": "Website Chat",
  "region": "eu",
  "defaultLanguage": "en",
  "autoTranslate": true,
  "translateToLanguage": "en",
  "fallbackLanguage": "sl",
  "aiProviderId": "PROVIDER_ID",
  "credentials": {},
  "responseTemplate": {},
  "autoReply": false,
  "autoApprove": false,
  "autoEnhance": false
}
FieldTypeRequiredNotes
typeenumyesEMAIL | FACEBOOK | INSTAGRAM | WHATSAPP | TELEGRAM | WEBSITE_CHAT
namestringyesMin length 1
regionstringno
defaultLanguagestringnoDefault en (agent language)
autoTranslatebooleannoDefault true
translateToLanguagestringnoAgent language to translate to
fallbackLanguagestringnoCustomer language guess for short/ambiguous messages
aiProviderIdstringnoFalls back to the org default provider
credentialsobjectyesChannel-specific credentials (e.g. IMAP/SMTP, page tokens)
responseTemplateobjectno
autoReplybooleannoDefault false
autoApprovebooleannoDefault false
autoEnhancebooleannoDefault false

Channel-type credential shapes (credentials) are validated separately — e.g. Email requires { host, port, username, password, from, secure?, imapHost?, imapPort?, imapSecure?, imapAllowSelfSigned? }; Facebook requires { pageId, accessToken, appSecret? }; Instagram requires { accountId, accessToken }. Credentials are stored encrypted (AES-256-GCM).

Conversations

MethodPathPurposeAuthKey params
GET/api/conversationsList conversationsSessionpage, pageSize, status, channelId, unread, assignedToId, language, search
POST/api/conversationsCreate conversationAGENT
GET/api/conversations/[id]Get oneSession
PATCH/api/conversations/[id]Update (status, priority, assignment, language, notes)Session
DELETE/api/conversations/[id]DeleteSession
GET/api/conversations/[id]/messagesList messagesSession
POST/api/conversations/[id]/messagesSend agent replyAGENT
POST/api/conversations/[id]/readMark readSession
POST/api/conversations/[id]/unreadMark unreadSession
POST/api/conversations/bulk-readMark many readSession

status filter values: OPEN | PENDING | CLOSED | ARCHIVED. pageSize is capped at 100 (default 20).

Send messagePOST /api/conversations/[id]/messages (verified body, sendMessageSchema):

{
  "conversationId": "CONVERSATION_ID",
  "content": "Thanks for reaching out — here's how to fix that.",
  "attachments": ["storage/path/file.png"]
}
FieldTypeRequiredNotes
conversationIdstringyesMust equal the [id] route param, else 400 VALIDATION_ERROR
contentstringyesMin length 1
attachmentsstring[]noStorage paths

Behavior: the message is created OUTBOUND. If the channel has autoTranslate on and a customer language is known, the message is created unapproved and translated in the background (the agent approves before it is sent). Sending consumes plan tokens; if the org is out of tokens the route returns 402 with code: "INSUFFICIENT_TOKENS". Success returns the created message with HTTP 201.

Messages

MethodPathPurposeAuth
POST/api/messages/[id]/approveApprove a queued/translated reply for sendingSession
POST/api/messages/[id]/generate-replyGenerate an AI reply suggestionSession
POST/api/messages/[id]/retranslateRe-run translation for the messageSession

FAQs

MethodPathPurposeAuthKey params
GET/api/faqsList FAQsSessionchannelId
POST/api/faqsCreate FAQADMIN
PATCH/api/faqs/[id]Update FAQSession
DELETE/api/faqs/[id]Delete FAQSession
POST/api/faqs/reorderReorder FAQsSession
POST/api/faqs/generateAI-generate FAQ suggestionsSession

Media

MethodPathPurposeAuth
POST/api/media/uploadUpload a file (multipart/form-data)Session
GET/api/media/[id]Fetch media metadata/fileSession
DELETE/api/media/[id]Delete mediaSession

Notifications

MethodPathPurposeAuth
GET/PUT/api/notifications/preferencesGet/update notification preferencesSession
GET/POST/api/notifications/integrationsList/configure notification integrationsSession
POST/api/notifications/push-subscriptionRegister a Web Push subscriptionSession

AI providers

MethodPathPurposeAuth
GET/api/ai-providersList configured providersSession
POST/api/ai-providersAdd a providerSession
PATCH/api/ai-providers/[id]Update a providerSession
DELETE/api/ai-providers/[id]Remove a providerSession

Agent tools

MethodPathPurposeAuth
GET/api/agent-toolsList org-level agent toolsSession
POST/api/agent-toolsCreate an agent toolSession
PATCH/api/agent-tools/[id]Update an agent toolSession
DELETE/api/agent-tools/[id]Delete an agent toolSession
GET/api/agent-tools/[id]/logsView tool-call logsSession

See Custom Agent Tools for the full tool anatomy.

Widget (public)

MethodPathPurposeAuth
GET/api/widget/[channelId]/configWidget configPublic, ~30/min/IP
GET/api/widget/[channelId]/faqsUp to 5 FAQ chipsPublic, ~30/min/IP
GET/api/widget/[channelId]/statusOnline statusPublic
POST/api/widget/[channelId]/uploadFile uploadPublic
POST/api/widget/messageSend message (WebSocket fallback)Public, ~20/min/visitor

See Widget Embed for payloads.

Webhooks (public)

MethodPathPurposeAuth
GET/api/webhooks/facebookVerify handshakeVerify token
POST/api/webhooks/facebookReceive Messenger eventsHMAC signature
GET/POST/api/webhooks/instagramVerify / receive Instagram eventsVerify token / HMAC
GET/POST/api/webhooks/whatsappVerify / receive WhatsApp eventsVerify token / HMAC

See Webhooks for handshake and signature details.