API & Integration
Use the Deskuss REST API to create tickets programmatically and trigger cron jobs remotely. The API covers ticket creation (JSON, XML, email) and cron execution — that's the full surface in this version.
API Keys
Every API request must be authenticated with a valid API key. API keys are managed from Settings → API Keys in the staff control panel (or directly under Deskuss → Settings → API Keys).
Creating an API Key
- Go to Deskuss → Settings → API Keys
- Click Add New Key
- Enter a descriptive label for the key (e.g., "CRM Integration", "Monitoring Service")
- Select the permissions for this key:
- Ticket Creation — allows creating new tickets via the API
- Cron Execution — allows triggering Deskuss cron tasks remotely
- Click Save
- Copy the generated key immediately — it is shown only once for security
Managing API Keys
From the API Keys management screen you can:
- Revoke — immediately disables the key — all requests using it will be rejected
- Toggle Permissions — enable or disable Ticket Creation and/or Cron Execution for an existing key
- View Last Used — the date and time of the last request made with this key
- View IP — the IP address of the last request made with this key
The Endpoints
All three endpoints are POST-only. The base URL is https://yoursite.com/deskuss/api/ followed by the endpoint path.
| Endpoint | Purpose | Permission required |
|---|---|---|
POST /api/tickets.json | Create a ticket from a JSON payload | Ticket Creation |
POST /api/tickets.xml | Create a ticket from an XML payload | Ticket Creation |
POST /api/tasks/cron | Trigger the internal cron tasks (overdue check, mail fetch, log cleanup, etc.) | Cron Execution |
Authentication
Every API request must include the API key in a custom HTTP header. Requests without a valid key receive a 401 Unauthorized response.
Header Format
X-Deskuss-API-Key: your_api_key_here
Authentication Flow
- Client sends a request with the
X-Deskuss-API-Keyheader - The Deskuss dispatcher hashes the key and compares it against stored hashes
- If the key is valid and has the required permission, the request is processed
- If the key is missing, invalid, revoked, or lacks the required permission, a
401or403response is returned
Creating a Ticket (JSON)
The tickets.json endpoint accepts a JSON payload with the ticket's fields. Subject and message are required; everything else is optional.
Endpoint
POST /api/tickets.json
Content-Type: application/json
X-Deskuss-API-Key: your_api_key_here
Request Body
{
"name": "Jane Smith",
"email": "jane@example.com",
"subject": "Cannot log in to my account",
"message": "I've been trying to log in for the past hour. The login button does nothing when I click it.",
"department": "Support",
"priority": "normal",
"topic": "Account Access"
}
Field Reference
| Field | Type | Required | Notes |
|---|---|---|---|
name | string | Yes | Customer's full name |
email | string | Yes | Customer's email address; becomes the From address on replies |
subject | string | Yes | Ticket subject line |
message | string | Yes | The full ticket body (plain text or HTML) |
department | string or int | No | Department name or ID. Defaults to the system's default department. |
priority | string | No | One of low, normal, high, emergency. Defaults to normal. |
topic | string or int | No | Help topic name or ID. Defaults to none. |
phone | string | No | Customer's phone number |
source | string | No | Tag for the ticket source. Defaults to API. |
ip | string | No | IP address to attribute the ticket to. Defaults to the API caller's IP. |
Success Response
{
"id": 1042,
"number": "#1042",
"created": "2026-06-12 14:32:01"
}
Error Responses
| Status | Meaning |
|---|---|
400 | Invalid payload — missing required field, malformed JSON, etc. |
401 | Missing X-Deskuss-API-Key header |
403 | API key is valid but does not have the Ticket Creation permission |
404 | Specified department, priority, or topic doesn't exist |
500 | Server error — see the system log |
Example: curl
curl -X POST https://example.com/deskuss/api/tickets.json \
-H "X-Deskuss-API-Key: your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"name": "Jane Smith",
"email": "jane@example.com",
"subject": "Cannot log in to my account",
"message": "I have been trying to log in for the past hour. The login button does nothing when I click it.",
"department": "Support",
"priority": "high"
}'
Example: PHP
<?php
$api_key = 'your_api_key_here';
$payload = [
'name' => 'Jane Smith',
'email' => 'jane@example.com',
'subject' => 'Cannot log in to my account',
'message' => 'I have been trying to log in for the past hour.',
'department' => 'Support',
'priority' => 'high',
];
$ch = curl_init('https://example.com/deskuss/api/tickets.json');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'X-Deskuss-API-Key: ' . $api_key,
'Content-Type: application/json',
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status === 200) {
$ticket = json_decode($response, true);
echo "Created ticket " . $ticket['number'] . "\n";
} else {
echo "Error $status: $response\n";
}
Example: Node.js
const fetch = require('node-fetch');
(async () => {
const response = await fetch('https://example.com/deskuss/api/tickets.json', {
method: 'POST',
headers: {
'X-Deskuss-API-Key': 'your_api_key_here',
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: 'Jane Smith',
email: 'jane@example.com',
subject: 'Cannot log in to my account',
message: 'I have been trying to log in for the past hour.',
department: 'Support',
priority: 'high',
}),
});
if (response.ok) {
const ticket = await response.json();
console.log('Created ticket', ticket.number);
} else {
console.error('Error', response.status, await response.text());
}
})();
Creating a Ticket (XML)
Identical to the JSON endpoint but with an XML payload. Useful for osTicket-compatible integrations.
Endpoint
POST /api/tickets.xml
Content-Type: application/xml
X-Deskuss-API-Key: your_api_key_here
Request Body
<?xml version="1.0" encoding="UTF-8"?>
<ticket>
<name>Jane Smith</name>
<email>jane@example.com</email>
<subject>Cannot log in to my account</subject>
<message>I have been trying to log in for the past hour.</message>
<department>Support</department>
<priority>high</priority>
<topic>Account Access</topic>
</ticket>
Success Response
<?xml version="1.0" encoding="UTF-8"?>
<response>
<id>1042</id>
<number>#1042</number>
<created>2026-06-12 14:32:01</created>
</response>
Creating a Ticket (Email)
The API also accepts email-format payloads sent with Content-Type: message/rfc822. Use this when piping from a system that produces email output (e.g., monitoring alerts that send mail). The raw email becomes the ticket; the From: header becomes the customer.
This endpoint is enabled by default. To disable it, set Settings → Tickets → Accept Email API to Off.
Cron Execution
Deskuss has internal cron tasks that run on a schedule (overdue check, mail fetching, log cleanup, draft cleanup, orphan-file cleanup, expired-session cleanup, table optimization). Normally these run via WP-Cron on every page load — see System Requirements.
The tasks/cron endpoint lets you trigger them on demand — useful for sites that disable WP-Cron and prefer a real system cron job that hits this endpoint every few minutes.
Endpoint
POST /api/tasks/cron
X-Deskuss-API-Key: your_api_key_here
Example: curl
curl -X POST https://example.com/deskuss/api/tasks/cron \
-H "X-Deskuss-API-Key: your_api_key_here"
Setting Up a Real Cron Job
Replace the WP-Cron schedule with a real system cron that hits the API endpoint:
*/5 * * * * curl -s -X POST https://example.com/deskuss/api/tasks/cron -H "X-Deskuss-API-Key: your_key" > /dev/null 2>&1
Add the wp-config.php constant define('DISABLE_WP_CRON', true); to fully replace WP-Cron with this approach.
Rate Limits & Errors
There are no per-key rate limits in this version, but Deskuss will return 429 Too Many Requests if a flood is detected (e.g., a misbehaving client retrying in a tight loop). The response is plain text with a short error message.
All errors include a short message in the response body. For full diagnostics, check Deskuss → System → Logs for the corresponding entry.
Best Practices
Security
- Always use HTTPS. API keys travel in a custom header, which is invisible to sniffers only on TLS.
- One key per integrating service — so you can revoke one without breaking the others.
- Restrict the Ticket Creation permission to keys that genuinely need it.
- Rotate keys on a schedule (every 6–12 months) and on personnel changes.
- Watch the Last Used column. A key that hasn't been used in months is a candidate for revocation.
Reliability
- Implement exponential backoff on 429 and 5xx responses.
- Log the response body on error — Deskuss returns a human-readable message in most cases.
- For mission-critical integrations, queue the API call locally and retry from the queue rather than retrying inline.
- Don't call the API inside a request that's already on a hot path (e.g., the customer's own request). The API call can take 100–500ms during ticket creation, especially if SMTP is being used.
Performance
- Batch related customer issues into a single ticket when possible — fewer tickets = less load on the cron and search indexes.
- Use the topic and department fields to route the ticket directly to the right team. Tickets with no department end up in the default queue and need to be moved.
What's Not in the API (Yet)
For completeness, here's what the API doesn't do in this version. If you need any of these, the workaround today is direct database access or staff-UI automation:
- List or read tickets (no
GET /api/tickets) - Update or close tickets (no
PUT /api/tickets/{id}) - Reply to tickets (no
POST /api/tickets/{id}/replies) - Manage departments, staff, SLAs, forms, or KB articles
- Webhooks — Deskuss doesn't push events out; you'd poll
tickets.jsonto detect new tickets (but that endpoint doesn't exist either — use the database) - Read or write KB articles
For a roadmap of upcoming API improvements, see the Changelog.