By area
Support
Read from the API’s own reference file every hour.
Open a ticket with Vocatech support from your own system.
Open a support ticket
POST/v1/
Opens a ticket with Vocatech support from your own system: a help desk sync, an automation, or your AI agent's "after a message" action. The ticket belongs to the account your key belongs to and is worked like any email or text to support.
One matter, one ticket. Send the same reference again within 7 days and your message is added to the ticket it opened (200, appended: true) instead of opening a new one. A reference that is a ticket key you were given reports back on that ticket.
Busy. 409 means that ticket is being worked right now. Retry after Retry-After seconds (60).
Send contact details flat (contact_name, contact_phone, contact_email, contact_company, contact_company_phone, reply_by) or in a contact object (name, phone, email, company, company_phone, reply_by). The flat field wins when both are sent.
Whose account. Support finds the customer's account from the business phone number first (contact_company_phone), then contact_phone, then caller_id. Send the business name and number when you have them.
Keys with the support scope can call this route.
Request
curl -X POST https://api.vocatech.com/v1/support/tickets \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"message": "Our fax line has been down since this morning. Please call me back.",
"contact_name": "Jordan Reyes",
"contact_phone": "7185550142",
"reply_by": "call",
"reference": "ticket-sync-2291",
"source": "Help desk sync"
}'const res = await fetch("https://api.vocatech.com/v1/support/tickets", {
method: "POST",
headers: {
Authorization: "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
message: "Our fax line has been down since this morning. Please call me back.",
contact_name: "Jordan Reyes",
contact_phone: "7185550142",
reply_by: "call",
reference: "ticket-sync-2291",
source: "Help desk sync",
}),
});
console.log(res.status, await res.json());import requests
r = requests.post(
"https://api.vocatech.com/v1/support/tickets",
headers={"Authorization": "Bearer YOUR_API_KEY"},
json={
"message": "Our fax line has been down since this morning. Please call me back.",
"contact_name": "Jordan Reyes",
"contact_phone": "7185550142",
"reply_by": "call",
"reference": "ticket-sync-2291",
"source": "Help desk sync",
},
timeout=30,
)
print(r.status_code, r.json())<?php
require 'vendor/autoload.php';
$client = new GuzzleHttp\Client([
'base_uri' => 'https://api.vocatech.com',
'headers' => ['Authorization' => 'Bearer YOUR_API_KEY'],
'http_errors' => false,
]);
$res = $client->post('/v1/support/tickets', [
'json' => [
'message' => 'Our fax line has been down since this morning. Please call me back.',
'contact_name' => 'Jordan Reyes',
'contact_phone' => '7185550142',
'reply_by' => 'call',
'reference' => 'ticket-sync-2291',
'source' => 'Help desk sync',
],
]);
echo $res->getStatusCode(), PHP_EOL, $res->getBody(), PHP_EOL;Body
| Field | Type | Description |
|---|---|---|
message required | string | What the person needs, in their own words. Up to 4,000 characters. Up to 4,000 characters. |
subject | string | One line. Cut to 120 characters. |
contact_name | string | Cut to 120 characters. |
contact_phone | string | A 10-digit US number. Punctuation and a leading 1 are allowed. |
contact_email | string (email) | |
contact_company | string | The business the person is calling about, as they gave it. Cut to 120 characters. |
contact_company_phone | string | The business's main phone number, as they gave it. Support matches the account on it first. A 10-digit US number, punctuation and a leading 1 allowed; anything else is left out and the ticket still opens. |
reply_by | string | How the person wants to hear back. One of call, text or email. |
caller_id | string | The number the person called from, when it differs from contact_phone. A 10-digit US number is kept; anything else (an extension, a withheld or an international number) is left out and the ticket still opens. |
reference | string | Your own id for this matter. The same reference within 7 days adds to the same ticket. A ticket key reports back on that ticket. Matches ^[A-Za-z0-9._:-]{1,80}$. |
source | string | The system that opened it, for example AI front desk or Help desk sync. Cut to 80 characters. |
contact | object | Another way to send the contact fields. A flat field wins when both are sent. |
contact. | string | |
contact. | string | |
contact. | string (email) | |
contact. | string | |
contact. | string | |
contact. | string | One of call, text or email. |
{
"message": "Our fax line has been down since this morning. Please call me back.",
"contact_name": "Jordan Reyes",
"contact_phone": "7185550142",
"contact_company": "Reyes Family Dental",
"contact_company_phone": "7185550100",
"reply_by": "call",
"reference": "ticket-sync-2291",
"source": "Help desk sync"
}Answers
reference opened.| Field | Type | Description |
|---|---|---|
ticket required | object | |
ticket. required | string | The ticket's key. Send it as reference later to report back on this ticket. |
ticket. required | string | |
ticket. required | string | For example open. |
ticket. required | string | When the ticket was opened, ISO 8601. |
ticket. required | boolean | True when your message was added to a ticket the same reference opened. |
{
"ticket": {
"key": "case-20260924-141502-3f9a1c7e5b2d4a6c8e0f1a3b5c7d9e2f",
"subject": "Message from Jordan Reyes",
"status": "open",
"created_at": "2026-09-24T14:15:02+00:00",
"appended": true
}
}| Field | Type | Description |
|---|---|---|
ticket required | object | |
ticket. required | string | The ticket's key. Send it as reference later to report back on this ticket. |
ticket. required | string | |
ticket. required | string | For example open. |
ticket. required | string | When the ticket was opened, ISO 8601. |
ticket. required | boolean | True when your message was added to a ticket the same reference opened. |
{
"ticket": {
"key": "case-20260924-141502-3f9a1c7e5b2d4a6c8e0f1a3b5c7d9e2f",
"subject": "Message from Jordan Reyes",
"status": "open",
"created_at": "2026-09-24T14:15:02+00:00",
"appended": false
}
}Retry-After seconds.| Header | Type | Description |
|---|---|---|
Retry-After | integer | Always 60. |
Example body
{
"error": {
"code": 409,
"type": "CONFLICT",
"message": "busy"
}
}Example bodies
{
"error": {
"code": 422,
"type": "UNPROCESSABLE_ENTITY",
"message": "message is required: what the person needs, in their own words."
}
}{
"error": {
"code": 422,
"type": "UNPROCESSABLE_ENTITY",
"message": "reply_by must be call, text or email."
}
}{
"error": {
"code": 422,
"type": "UNPROCESSABLE_ENTITY",
"message": "contact_phone must be a 10 digit US number."
}
}{
"error": {
"code": 422,
"type": "UNPROCESSABLE_ENTITY",
"message": "reference may use letters, digits, dot, underscore, colon and dash, up to 80 characters."
}
}tickets counter is full (10 a minute, 200 a day per key), or another request limit was reached. Wait Retry-After seconds.| Header | Type | Description |
|---|---|---|
Retry-After | integer | Seconds to wait before you try again. |
Example body
{
"error": "Rate limit exceeded",
"period": "minute",
"limit": 10,
"counter": "tickets",
"retry_after": 42
}Example body
{
"error": {
"code": 502,
"type": "ERROR",
"message": "The support desk could not take the ticket right now. Try again in a minute."
}
}| Header | Type | Description |
|---|---|---|
Retry-After | integer | Seconds to wait before you try again. |
Example body
{
"error": {
"code": 503,
"type": "ERROR",
"message": "The support desk is not available right now."
}
}