API Reference
Everything you need to integrate Velox into your workflow. Authenticate, query tickets, manage conversations, and more.
Introduction
The Velox API gives you programmatic access to your customer operations data. Use it to create tickets, pull conversation history, sync contacts with your CRM, or build custom dashboards.
Base URL
https://velox-app-production.up.railway.app/api/v1
Authentication
Pass your API key via the X-API-Key header on every request. You can generate keys from Settings → API Keys in the Velox dashboard.
Rate Limits
All endpoints are rate-limited to 100 requests per minute per API key. Exceeding this limit returns a 429 status code with a Retry-After header.
Response Format
Every response returns JSON with a consistent envelope. Successful responses include data and optional meta fields.
Tickets
Tickets represent support requests from customers. Each ticket has a status, priority, and an associated conversation thread.
/v1/ticketsRetrieve a paginated list of tickets. Filter by status, priority, or free-text search.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| status | string | No | Filter by ticket status (open, pending, resolved, closed) |
| priority | string | No | Filter by priority (low, medium, high, urgent) |
| limit | integer | No | Number of results per page (default 50, max 100) |
| offset | integer | No | Offset for pagination (default 0) |
| search | string | No | Free-text search across subject and description |
Example Request
curl -X GET "https://velox-app-production.up.railway.app/api/v1/tickets?status=open&limit=10" \
-H "X-API-Key: your_api_key"Example Response
{
"data": [
{
"id": "tkt_abc123",
"subject": "Login issue",
"status": "open",
"priority": "high",
"contactEmail": "jane@acme.com",
"createdAt": "2026-03-28T14:22:00Z"
}
],
"meta": {
"total": 42,
"limit": 10,
"offset": 0
},
"error": null
}/v1/tickets/:idRetrieve a single ticket by ID, including its full conversation thread.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| id | string | Yes | The ticket ID (path parameter) |
Example Request
curl -X GET "https://velox-app-production.up.railway.app/api/v1/tickets/tkt_abc123" \
-H "X-API-Key: your_api_key"Example Response
{
"data": {
"id": "tkt_abc123",
"subject": "Login issue",
"status": "open",
"priority": "high",
"contactEmail": "jane@acme.com",
"messages": [
{
"id": "msg_001",
"body": "I cannot log in to my account.",
"sender": "customer",
"createdAt": "2026-03-28T14:22:00Z"
}
],
"createdAt": "2026-03-28T14:22:00Z"
},
"error": null
}/v1/ticketsCreate a new support ticket.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| subject | string | Yes | Short summary of the issue |
| description | string | Yes | Detailed description of the issue |
| priority | string | No | Priority level (low, medium, high, urgent). Defaults to medium |
| contactEmail | string | Yes | Email address of the person reporting the issue |
Example Request
curl -X POST "https://velox-app-production.up.railway.app/api/v1/tickets" \
-H "X-API-Key: your_api_key" \
-H "Content-Type: application/json" \
-d '{
"subject": "Cannot reset password",
"description": "The reset link returns a 404.",
"priority": "high",
"contactEmail": "jane@acme.com"
}'Example Response
{
"data": {
"id": "tkt_def456",
"subject": "Cannot reset password",
"status": "open",
"priority": "high",
"contactEmail": "jane@acme.com",
"createdAt": "2026-04-06T09:15:00Z"
},
"error": null
}/v1/tickets/:idUpdate an existing ticket. All fields are optional; only provided fields are modified.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| id | string | Yes | The ticket ID (path parameter) |
| status | string | No | New status (open, pending, resolved, closed) |
| priority | string | No | New priority (low, medium, high, urgent) |
| assignedTo | string | No | User ID of the agent to assign |
Example Request
curl -X PATCH "https://velox-app-production.up.railway.app/api/v1/tickets/tkt_abc123" \
-H "X-API-Key: your_api_key" \
-H "Content-Type: application/json" \
-d '{ "status": "resolved", "assignedTo": "usr_agent01" }'Example Response
{
"data": {
"id": "tkt_abc123",
"subject": "Login issue",
"status": "resolved",
"priority": "high",
"assignedTo": "usr_agent01",
"updatedAt": "2026-04-06T10:30:00Z"
},
"error": null
}Conversations
Conversations aggregate messages across channels (email, live chat, widget). Use this endpoint to pull cross-channel history.
/v1/conversationsList all conversations across channels (email, chat, widget). Filter by channel or status.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| channel | string | No | Filter by channel (email, chat, widget) |
| status | string | No | Filter by status (active, archived) |
| limit | integer | No | Number of results per page (default 50, max 100) |
| offset | integer | No | Offset for pagination (default 0) |
Example Request
curl -X GET "https://velox-app-production.up.railway.app/api/v1/conversations?channel=email&limit=20" \
-H "X-API-Key: your_api_key"Example Response
{
"data": [
{
"id": "conv_xyz789",
"channel": "email",
"status": "active",
"subject": "Billing inquiry",
"participantEmail": "john@acme.com",
"lastMessageAt": "2026-04-05T18:45:00Z"
}
],
"meta": {
"total": 128,
"limit": 20,
"offset": 0
},
"error": null
}Contacts
Contacts represent the people your team interacts with. Each contact has a computed health tier based on engagement signals.
/v1/contactsRetrieve a paginated list of contacts. Filter by customer health tier.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| healthTier | string | No | Filter by health tier (healthy, at-risk, churned) |
| limit | integer | No | Number of results per page (default 50, max 100) |
| offset | integer | No | Offset for pagination (default 0) |
Example Request
curl -X GET "https://velox-app-production.up.railway.app/api/v1/contacts?healthTier=at-risk&limit=25" \
-H "X-API-Key: your_api_key"Example Response
{
"data": [
{
"id": "ctc_lmn456",
"name": "Jane Doe",
"email": "jane@acme.com",
"company": "Acme Corp",
"healthTier": "at-risk",
"lastSeenAt": "2026-04-04T12:00:00Z"
}
],
"meta": {
"total": 87,
"limit": 25,
"offset": 0
},
"error": null
}Errors
When a request fails, the API returns a consistent error envelope. The HTTP status code reflects the error category, and the body contains machine-readable details.
| Status | Code | Meaning |
|---|---|---|
| 400 | BAD_REQUEST | Invalid or missing parameters |
| 401 | UNAUTHORIZED | Missing or invalid API key |
| 403 | FORBIDDEN | API key lacks required permissions |
| 404 | NOT_FOUND | Resource does not exist |
| 429 | RATE_LIMITED | Too many requests |
| 500 | INTERNAL_ERROR | Something went wrong on our end |
Error Response Example
{
"data": null,
"error": {
"code": "NOT_FOUND",
"message": "Ticket not found"
}
}