HeskAPI Documentation
REST API for HESK 3.7.10 · PHP 8.1+
Quick Start
Upload the drop-in zip
Extract the HeskAPI zip into your HESK root directory (same folder as hesk_settings.inc.php). The module adds an api/ directory and an admin/ panel page — no HESK files are modified.
Your license is already in place
Your download includes a ready-to-use heskapi_license.php, pre-filled and locked to your domain — just keep it in the HESK root alongside the other files. The API validates this license against your domain on startup, so don't edit or move it. (Bought before this was automatic? Re-download from your activation email, or paste the key we sent into a heskapi_license.php in the HESK root.)
Make your first API call
Send a request to /api/v1/?action=list_tickets with your API key. You should receive a JSON response with your HESK tickets.
Authentication
Every request to the HeskAPI requires an API key. Generate and manage keys from the HeskAPI admin panel inside HESK (Admin → HeskAPI Manager).
Pass the key via HTTP header (recommended):
X-HESK-API-Key: your_api_key_here
Or via query parameter:
GET /api/v1/?action=list_tickets&key=your_api_key_here
API keys can be rotated at any time from the admin panel without downtime.
Rate Limiting
HeskAPI enforces configurable per-key rate limits using atomic database counters.
| Header | Description |
|---|---|
X-RateLimit-Limit | Max requests per minute for this key |
X-RateLimit-Remaining | Requests remaining in current window |
Retry-After | Seconds until the rate limit resets (only on 429) |
When the limit is exceeded the API returns HTTP 429 with a JSON error body. Configure the limit per API key from the admin panel.
Endpoints
/api/v1/?action=list_tickets
Returns a paginated list of HESK tickets.
| Parameter | Type | Description |
|---|---|---|
page | int | Page number (default: 1) |
per_page | int | Results per page (default: 25, max: 100) |
status | int | Filter by status: 0=open, 1=resolved, 2=in progress |
category | int | Filter by HESK category ID |
/api/v1/?action=search_tickets
Full-text search across ticket subjects and messages.
| Parameter | Type | Description |
|---|---|---|
q | string | Search query (required) |
page | int | Page number |
per_page | int | Results per page |
/api/v1/?action=create_ticket
Creates a new HESK ticket. Supports multipart/form-data for file attachments. Triggers native HESK staff email notifications.
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Customer name |
email | string | Yes | Customer email |
subject | string | Yes | Ticket subject |
message | string | Yes | Ticket message body |
category | int | No | HESK category ID (default: 1) |
priority | int | No | 0=Critical, 1=High, 2=Medium, 3=Low |
attachment | file | No | File attachment (multipart only) |
/api/v1/?action=update_ticket
Updates fields on an existing ticket (status, priority, category, or custom fields).
| Field | Type | Required | Description |
|---|---|---|---|
trackid | string | Yes | Ticket track ID (e.g. ABC-123456) |
status | int | No | New status: 0=open, 1=resolved, 2=in progress |
priority | int | No | New priority (0–3) |
category | int | No | New category ID |
/api/v1/?action=close_ticket
Marks a ticket as resolved.
| Field | Type | Required | Description |
|---|---|---|---|
trackid | string | Yes | Ticket track ID |
Error Codes
| HTTP Status | Error Code | Description |
|---|---|---|
| 401 | invalid_key | Missing or invalid API key |
| 403 | ip_banned | Requesting IP is in HESK's ban list |
| 403 | email_banned | Email address is in HESK's ban list |
| 403 | api_disabled | API is disabled in the admin panel |
| 404 | ticket_not_found | The specified track ID does not exist |
| 422 | validation_error | Missing or invalid request parameter |
| 429 | rate_limit | Rate limit exceeded — see Retry-After header |
| 500 | server_error | Internal server error |
All error responses include a JSON body: {"status":"error","code":"...","message":"..."}
Code Examples
PHP — List tickets
$ch = curl_init('https://yoursite.com/hesk/api/v1/?action=list_tickets');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['X-HESK-API-Key: your_api_key_here'],
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
PHP — Create ticket
$ch = curl_init('https://yoursite.com/hesk/api/v1/?action=create_ticket');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => [
'name' => 'Jane Smith',
'email' => '[email protected]',
'subject' => 'Login issue',
'message' => 'I cannot log in since yesterday.',
'category' => 1, // required: target HESK category ID
],
CURLOPT_HTTPHEADER => ['X-HESK-API-Key: your_api_key_here'],
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
JavaScript (fetch) — List tickets
const res = await fetch('https://yoursite.com/hesk/api/v1/?action=list_tickets', {
headers: { 'X-HESK-API-Key': 'your_api_key_here' },
});
const data = await res.json();
Looking for Discord & Slack Webhooks?
The webhooks are separate drop-in scripts that post new ticket alerts to your Discord or Slack workspace. No API required — they connect directly to your HESK database via cron.
View Webhook Docs