API reference
Sample: Create a ticket
Create a support ticket on behalf of a customer. The ticket starts in the Open status and is assigned by your routing rules unless you set assignee_id.
This is a sample page
"Acme Tickets" is a made-up API. This page shows what an API reference article looks like with the PinkDocs API blocks. Read Write API reference docs to build your own.
POST
https://api.example.com/v1/ticketshttps://api.example.com/v1/ticketsRequest
curl -X POST "https://api.example.com/v1/tickets?notify=true" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"subject": "Cannot log in after password reset",
"description": "The reset link says it has expired.",
"priority": "high",
"requester_email": "jane@example.com",
"tags": ["login", "password"]
}'const response = await fetch('https://api.example.com/v1/tickets?notify=true', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
subject: 'Cannot log in after password reset',
description: 'The reset link says it has expired.',
priority: 'high',
requester_email: 'jane@example.com',
tags: ['login', 'password']
})
});
const ticket = await response.json();import requests
response = requests.post(
"https://api.example.com/v1/tickets",
params={"notify": True},
headers={"Authorization": "Bearer YOUR_API_KEY"},
json={
"subject": "Cannot log in after password reset",
"description": "The reset link says it has expired.",
"priority": "high",
"requester_email": "jane@example.com",
"tags": ["login", "password"],
},
)
ticket = response.json()$response = wp_remote_post('https://api.example.com/v1/tickets?notify=true', [
'headers' => [
'Authorization' => 'Bearer YOUR_API_KEY',
'Content-Type' => 'application/json',
],
'body' => wp_json_encode([
'subject' => 'Cannot log in after password reset',
'description' => 'The reset link says it has expired.',
'priority' => 'high',
'requester_email' => 'jane@example.com',
'tags' => ['login', 'password'],
]),
]);
$ticket = json_decode(wp_remote_retrieve_body($response), true);body := strings.NewReader(`{"subject":"Cannot log in after password reset","priority":"high","requester_email":"jane@example.com"}`)
req, _ := http.NewRequest("POST", "https://api.example.com/v1/tickets?notify=true", body)
req.Header.Set("Authorization", "Bearer YOUR_API_KEY")
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)require "net/http"
require "json"
uri = URI("https://api.example.com/v1/tickets?notify=true")
req = Net::HTTP::Post.new(uri, "Authorization" => "Bearer YOUR_API_KEY", "Content-Type" => "application/json")
req.body = { subject: "Cannot log in after password reset", priority: "high", requester_email: "jane@example.com" }.to_json
res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }Response
Ticket created
{
"id": "tkt_8f2a91",
"number": 1042,
"subject": "Cannot log in after password reset",
"status": "open",
"priority": "high",
"requester": {
"email": "jane@example.com",
"name": null
},
"assignee_id": null,
"tags": ["login", "password"],
"created_at": "2026-10-07T09:30:00Z",
"updated_at": "2026-10-07T09:30:00Z"
}The request body is not valid JSON
{
"error": "invalid_request",
"message": "Unexpected token } in JSON at position 84"
}Missing or invalid API key
{
"error": "unauthorized",
"message": "Add an Authorization: Bearer header with a valid API key."
}A field failed validation
{
"error": "validation_failed",
"fields": {
"requester_email": "Must be a valid email address.",
"priority": "Must be one of: low, normal, high, urgent."
}
}Too many requests
{
"error": "rate_limited",
"retry_after": 30
}Something went wrong on our side
{
"error": "server_error",
"request_id": "req_41c9e0"
}Authentication
- Header
AuthorizationstringrequiredYour API key as a bearer token, e.g.Bearer sk_live_…. Create keys in **Settings → API keys**. - Header
Idempotency-KeystringAny unique value (a UUID works). Sending the same key again within 24 hours returns the first ticket instead of creating a duplicate.
Query parameters
- Query
notifybooleandefault:trueEmail the requester a confirmation that the ticket was received.
Body
subjectstringrequiredA short summary shown in ticket lists. Up to 200 characters.descriptionstringThe full message. Markdown is supported.prioritystringdefault:normalOne oflow,normal,highorurgent.requester_emailstringrequiredThe customer’s email address. A new contact is created if it doesn’t exist yet.tagsstring[]Labels for filtering and reports, e.g.["billing"].custom_fieldsobjectValues for your custom fields, keyed by field ID, e.g.{"cf_plan": "pro"}.assignee_idstringThe agent to assign. Leave empty to use your routing rules.group_idstringdeprecatedUseteam_idinstead. Still accepted until v2.
Rate limits
Each API key can create up to 100 tickets per minute. Over the limit you get a 429 response with a retry_after value in seconds.
Avoid duplicate tickets
If your request may be retried (for example from a webhook or a job queue), always send an
Idempotency-Key header.Errors
| Status | When it happens |
|---|---|
400 | The body isn't valid JSON. |
401 | The API key is missing, revoked or wrong. |
422 | A field is missing or has the wrong format; fields says which. |
429 | You sent too many requests; wait retry_after seconds. |
500 | Something went wrong on our side; include the request_id when you contact support. |
Was this page helpful?
Great! What worked best for you?
Please provide additional details about your experience.
Thank you for your feedback!
We appreciate your input.
