Host: the API is hosted at
helpmesh.io. Don't use app.helpmesh.io — that's the dashboard subdomain and is interpreted as a tenant slug (you'll get HM-TENANT-NOT_FOUND). The official @helpmesh-io/sdk uses the correct host by default.Authentication: Include your API key as a Bearer token in the
Authorization header.Versioning: the OpenAPI spec carries an
info.version that tracks the API contract — it bumps when endpoints, request bodies, or response shapes change. The HelpMesh product version (shown on /changelog and in the npm SDK) tracks the whole platform and bumps far more often. The two move independently. Pin to the URL path — /api/v1 — that's the only breaking-change boundary you need to care about.Threads
Manage customer support threads. Each thread represents a conversation with a customer across any channel.
Code samples
Query Parameters
| Name | Type | Description |
|---|---|---|
| status optional | string | Filter by status: open, pending, resolved, closed |
| cursor optional | string | Pagination cursor from previous response |
| limit optional | integer | Number of results per page (default: 20, max: 100) |
Example Request (curl)
curl https://helpmesh.io/api/v1/threads \
-H "Authorization: Bearer $HELPMESH_API_KEY"Response 200
{
"data": [
{
"id": "thr_01H8X3YVKM",
"subject": "Cannot access my dashboard",
"status": "open",
"priority": "high",
"channel": "email",
"assignee": {
"id": "usr_01H8X3Z",
"name": "Sarah Chen"
},
"customer": {
"id": "cst_01H8X4A",
"email": "user@example.com"
},
"createdAt": "2026-07-11T08:47:33Z",
"updatedAt": "2026-07-11T11:37:33Z"
}
],
"meta": {
"cursor": "eyJpZCI6InRocl8wMUg4WDNZVktNIn0",
"hasMore": true,
"total": 142
}
}Request Body
| Name | Type | Description |
|---|---|---|
| title required | string | Ticket title (industry shape). Aliases: subject (strict shape). |
| body required | string | Initial message body (text or sanitized HTML). |
| requester required | object | Customer: { email, name? } — auto-upserts the Customer record on create. |
| external_reference_id optional | string | Your internal ticket id. Repeated POSTs with the same value return the existing thread (idempotent retry). |
| tags optional | string[] | Free-form tags. Auto-converted to tenant Labels on create. |
| inboxId optional | string | Target inbox. If omitted, routes to the tenant's isDefault inbox (or the oldest active EMAIL/API inbox as fallback). |
| priority optional | string | Priority: LOW, NORMAL, HIGH, URGENT (default: NORMAL). |
| channel optional | string | Origin channel: EMAIL, API, WIDGET, SLACK, WHATSAPP, SMS, VOICE (default: API). |
Example Request (curl)
curl -X POST https://helpmesh.io/api/v1/threads \
-H "Authorization: Bearer $HELPMESH_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "Cannot access my dashboard",
"body": "I am getting a 403 error on the analytics page.",
"requester": { "email": "user@example.com", "name": "Jane Doe" },
"external_reference_id": "your-ticket-id-1f18d868",
"tags": ["billing", "p1"]
}'Request Body Schema
// Industry-compatible shape (recommended — used by Zendesk / Freshdesk / Intercom integrators)
{
"title": "Cannot access my dashboard",
"body": "I'm getting a 403 error when trying to access the analytics page.",
"requester": {
"email": "user@example.com",
"name": "Jane Doe"
},
"external_reference_id": "your-ticket-id-1f18d868",
"tags": ["billing", "p1"]
}
// Response includes the HelpMesh ticket number for your ticket-mapping table:
// {
// "data": {
// "id": "cmoo7nqw200072cwp7r6yu5qr",
// "publicNumber": 16,
// "ticketNumber": "PRO-6-000016",
// "externalRef": "your-ticket-id-1f18d868",
// ...
// }
// }
// Strict id-based shape (for callers that already have inboxId + customerId):
{
"inboxId": "inb_01H8X4A",
"customerId": "cst_01H8X4A",
"subject": "Cannot access my dashboard",
"body": "I'm getting a 403 error when trying to access the analytics page.",
"channel": "API",
"priority": "HIGH"
}