Skip to main content

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.

HeaderDescription
X-RateLimit-LimitMax requests per minute for this key
X-RateLimit-RemainingRequests remaining in current window
Retry-AfterSeconds 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

GET /api/v1/?action=list_tickets

Returns a paginated list of HESK tickets.

ParameterTypeDescription
pageintPage number (default: 1)
per_pageintResults per page (default: 25, max: 100)
statusintFilter by status: 0=open, 1=resolved, 2=in progress
categoryintFilter by HESK category ID
GET /api/v1/?action=search_tickets

Full-text search across ticket subjects and messages.

ParameterTypeDescription
qstringSearch query (required)
pageintPage number
per_pageintResults per page
POST /api/v1/?action=create_ticket

Creates a new HESK ticket. Supports multipart/form-data for file attachments. Triggers native HESK staff email notifications.

FieldTypeRequiredDescription
namestringYesCustomer name
emailstringYesCustomer email
subjectstringYesTicket subject
messagestringYesTicket message body
categoryintNoHESK category ID (default: 1)
priorityintNo0=Critical, 1=High, 2=Medium, 3=Low
attachmentfileNoFile attachment (multipart only)
POST /api/v1/?action=update_ticket

Updates fields on an existing ticket (status, priority, category, or custom fields).

FieldTypeRequiredDescription
trackidstringYesTicket track ID (e.g. ABC-123456)
statusintNoNew status: 0=open, 1=resolved, 2=in progress
priorityintNoNew priority (0–3)
categoryintNoNew category ID
POST /api/v1/?action=reply_ticket

Posts a staff reply to a ticket. Triggers native HESK customer email notification.

FieldTypeRequiredDescription
trackidstringYesTicket track ID
messagestringYesReply body
attachmentfileNoFile attachment (multipart)
POST /api/v1/?action=close_ticket

Marks a ticket as resolved.

FieldTypeRequiredDescription
trackidstringYesTicket track ID

Error Codes

HTTP StatusError CodeDescription
401invalid_keyMissing or invalid API key
403ip_bannedRequesting IP is in HESK's ban list
403email_bannedEmail address is in HESK's ban list
403api_disabledAPI is disabled in the admin panel
404ticket_not_foundThe specified track ID does not exist
422validation_errorMissing or invalid request parameter
429rate_limitRate limit exceeded — see Retry-After header
500server_errorInternal 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();