Documentation
Everything you need to get started with SupportLayer, manage your helpdesk, and integrate with external tools via the REST API.
Getting started
Set up your helpdesk in under five minutes.
- Create your account — visit the registration page and enter your name, email, company name, and a password. Choose an MFA policy for your organization (disabled, optional, or required).
- Verify your email — check your inbox for a verification link. You must confirm your email before signing in.
- Sign in — after verification, sign in at the login page. If your organization requires MFA, you will be prompted to enroll on first login.
- Explore your workspace — your organization is pre-configured with default ticket statuses (Open, In Progress, On Hold, With Client, Closed), urgency levels (Low, Normal, High, Critical), categories (General, Bug, Account), and role groups. Start creating tickets immediately.
Workspaces & organizations
Each organization is a fully isolated workspace with its own tickets, users, and settings.
All tickets, users, settings, and data belong to a single workspace and cannot be accessed from another. This tenant isolation is enforced at the database level.
A single user account can belong to multiple organizations. After signing in, if you have access to more than one workspace, you will be asked to choose which one to enter. You can switch organizations at any time using the Switch organization option in the sidebar.
Working with tickets
Tickets are the core of SupportLayer — every request, bug, or question lives here.
Each ticket has:
- Subject — a short summary of the request.
- Body — a detailed description of the issue or request.
- Status — tracks the lifecycle (Open, In Progress, On Hold, With Client, Closed). Administrators can add custom statuses.
- Urgency — determines the SLA first-response deadline (Critical: 60 min, High: 120 min, Normal: 240 min, Low: 480 min).
- Category — organizes tickets by type (General, Bug, Account, or custom categories you define).
- Tags — flexible labels with optional color coding for cross-cutting classification.
- Product — associates the ticket with a specific product, useful for multi-product teams.
- Assignee — the agent or manager responsible for the ticket.
- Reporter — the user who created the ticket.
Creating a ticket
Navigate to Tickets in the sidebar and click New ticket. Fill in the subject, body, and optionally set a category, urgency, product, tags, and assignee. The ticket is automatically assigned the "Open" status and SLA tracking begins based on the urgency level.
Replying and internal notes
Open a ticket and use the reply form at the bottom to add a message. Check the Internal note checkbox to create a note visible only to agents and managers — end users will not see internal notes. The first non-internal reply by someone other than the reporter is recorded as the first response for SLA tracking.
Attachments
Upload files directly from the ticket detail page. Attachments are stored securely and served through authenticated endpoints — there are no public file URLs.
Bulk actions
From the ticket list, select multiple tickets using the checkboxes and choose a bulk action: Close, Assign to me, or Unassign.
Escalation
Agents with escalation permission can escalate a ticket to a service manager or other authorized user. The previous assignee is preserved in the escalation history for audit purposes.
Filtering tickets
The ticket list supports filtering by:
- Search — matches ticket subject or ID.
- Status — filter by a specific status, all open tickets, or SLA-overdue tickets.
- Assignee — filter by a specific agent, "assigned to me", or unassigned.
- Category — filter by ticket category.
- Product — filter by product.
- SLA — show tickets that are at risk (SLA due within 2 hours).
SLA management
Automatic first-response tracking with pause/resume logic that reflects real agent effort.
SupportLayer tracks first-response SLAs automatically based on ticket urgency:
| Urgency | First response target |
|---|---|
| Critical | 60 minutes |
| High | 120 minutes (2 hours) |
| Normal | 240 minutes (4 hours) |
| Low | 480 minutes (8 hours) |
SLA pause and resume
When a ticket moves to a status marked as Pauses SLA (by default, "On Hold" and "With Client"), the SLA clock pauses. When the ticket returns to a non-pausing status, the deadline is extended by the duration of the pause. This ensures your SLA metrics reflect agent effort, not time waiting on a customer.
Changing urgency
If a ticket's urgency is changed, the SLA deadline is recalculated from the ticket's creation time using the new urgency's response window, accounting for any accumulated pause time.
Business hours
Administrators can configure business hours from Ticket settings in the admin sidebar. When SLA applies during business hours only is enabled, SLA deadlines are calculated using business time only — weekends and non-working hours are excluded. Configure:
- Timezone — the timezone used for business hours calculations.
- Start / End time — the daily business hours window (e.g. 09:00–17:00).
- Working days — select which days of the week are working days.
When business hours are enabled, SLA deadlines are automatically extended to account for non-working time. Pause/resume behaviour continues to work as expected alongside business hours.
SLA warning emails
When a ticket is approaching its SLA deadline (within 30 minutes), SupportLayer automatically sends a warning email to the assigned agent. This gives agents a heads-up before a breach occurs. Agents can disable SLA warning emails from their Notification preferences in the settings sidebar.
Dashboard indicators
The dashboard shows real-time SLA health:
- Overdue — tickets where the SLA deadline has passed without a first response.
- At risk — tickets with an SLA deadline within the next 2 hours.
Roles & permissions
Four access groups map to real team structures, from end users to administrators.
| Role | Description | Permissions |
|---|---|---|
| End User | Customers or external requesters | View own tickets, create tickets |
| Support Agent | Front-line support staff | View all tickets, create, edit, assign, escalate, manage tags |
| Service Manager | Senior support staff and escalation targets | All agent permissions plus: receive escalations, manage categories and urgencies |
| Administrator | Workspace owners and admins | All permissions including: manage settings, manage company users, manage end users, manage statuses |
Seat counting: Support Agents and Service Managers count toward your plan's agent seat limit. Administrators and End Users are unlimited on all plans.
Managing users
Add team members and customers to your workspace with automatic account provisioning.
Company users (agents, managers, administrators)
Navigate to Company users in the admin sidebar. From here you can:
- Add a user — enter their name, email, and role. If they don't have a SupportLayer account, one is created automatically and they receive an invite email with a temporary password.
- Change role — promote or change a user's access group. The system enforces agent seat limits based on your plan.
- Suspend or restore — temporarily revoke a user's access without deleting their account. The system prevents suspending the last administrator.
- Update names — edit first and last names inline.
End users (customers)
Navigate to End users in the admin sidebar. End users can create and view their own tickets but cannot see other users' tickets or access admin features. Adding an end user works the same way as company users — accounts are auto-created with invite emails if needed.
End users can also be managed programmatically via the End Users API.
Branding & customization
Make the portal yours with custom logos, colours, and ticket configuration.
Navigate to Branding in the admin sidebar to customize your workspace:
- Logo — upload your company logo. It appears in the portal sidebar for all users in your workspace.
- Primary color — sets the sidebar background and primary action color.
- Accent color — sets secondary highlight colors throughout the interface.
Customers and end users see your branded workspace, not a generic SupportLayer interface.
Ticket configuration
Navigate to Ticket settings in the admin sidebar to customize:
- Statuses — add custom statuses with optional SLA pausing. Default statuses (Open, In Progress, On Hold, With Client, Closed) are locked and cannot be deleted.
- Urgency levels — customize urgency names and SLA response windows.
- Categories — organize tickets by type. Categories can be hierarchical (parent/child).
- Products — define products that tickets can be associated with, useful for multi-product teams to sort and filter their work.
- Tags — create tags with optional colors for flexible ticket labeling.
Reply templates
Navigate to Reply templates (canned responses) in the admin sidebar. Create pre-written responses that agents can insert with one click when replying to tickets. Each template has a title and body text.
Security & MFA
Enterprise-grade security defaults on every account, with no extra cost or configuration.
- Email verification — all accounts must verify their email address before signing in.
- Two-factor authentication (MFA) — SupportLayer supports TOTP-based two-factor authentication (compatible with Google Authenticator, Authy, 1Password, and similar apps). Administrators can set the organization's MFA policy to:
- Disabled — MFA is not available.
- Optional — users can choose to enroll.
- Required — all users must enroll before accessing the workspace.
- Password security — passwords are hashed with bcrypt. Minimum length is 8 characters.
- Tenant isolation — all data is scoped to your organization at the database level. Queries are automatically filtered to prevent cross-tenant data access.
- CSRF protection — all state-changing actions are protected against cross-site request forgery.
- Authenticated file access — attachments are served through authenticated endpoints only.
Live chat widget
Embed a real-time chat widget on your website — agents reply from the portal, no extra tools needed.
Setting up the widget
- Enable the widget — navigate to Chat widget in the admin sidebar and check Enable live chat widget.
- Customize — set a welcome message and choose an accent colour for the chat bubble and header. If you leave the colour blank, it uses your branding primary colour.
- Embed — copy the embed snippet from the settings page and paste it before the closing
</body>tag on every page where you want the widget to appear:
<script src="https://www.supportlayer.app/static/widget/supportlayer-chat.js"
data-widget-key="YOUR_WIDGET_KEY" async></script>
The widget key identifies your workspace. You can regenerate it from the settings page if it is compromised — you will need to update the embed code on your website afterwards.
How it works for visitors
The widget appears as a floating chat bubble in the bottom-right corner of your website. When a visitor clicks it, they can optionally enter their name and email, then start a conversation. Messages are delivered in real time via polling. If the visitor leaves and returns, their session is automatically resumed from local storage.
How it works for agents
Agents with ticket-editing permissions see a Live Chat link in the portal sidebar. The chat list shows all open conversations with visitor details, the last message preview, and the assigned agent. Click a conversation to view the full thread, reply, and close the chat when resolved. The first agent to reply is automatically assigned to the conversation.
Email channel
Forward your support inbox to SupportLayer and every email becomes a ticket automatically.
Setting up the email channel
- Find your forwarding address — navigate to Email channel in the admin sidebar. Your unique forwarding address is displayed at the top of the page (e.g.
your-org@inbound.supportlayer.app). - Configure forwarding — in your email provider (Gmail, Outlook, etc.), set up a forwarding rule to send messages from your support inbox (e.g.
support@your-company.com) to the forwarding address shown. - Start receiving tickets — every forwarded email will create a new ticket with the sender as the reporter.
How it works
- New tickets — an email sent to your forwarding address creates a ticket. The email subject becomes the ticket subject, the body becomes the ticket description, and the sender is set as the reporter.
- Auto-created users — if the sender's email address doesn't match an existing user, a new end user is automatically created and added to your workspace.
- Reply threading — when agents reply to a ticket from the portal, the notification email includes a
Reply-Toheader that routes replies back to the correct ticket. When the customer replies to the notification, their reply is appended to the existing ticket as a message instead of creating a new ticket. - SLA tracking — email-created tickets follow the same SLA rules as any other ticket. The SLA clock starts from the moment the email is received.
Using your own email address
Customers continue to email your regular support address (e.g. support@your-company.com). The forwarding happens behind the scenes — they never see the SupportLayer forwarding address. When your agents reply from the portal, the customer receives a notification email they can reply to directly.
Integrations
Connect SupportLayer with external tools to streamline your workflow.
ProjectLayer
The ProjectLayer integration lets agents convert support tickets into backlog items in ProjectLayer directly from the ticket view.
Setting up the connection
- In ProjectLayer, go to Settings → API Keys and generate a new key. Copy the
pl_live_...token. - In SupportLayer, navigate to Admin → Integrations.
- Enter your ProjectLayer API URL (e.g.
https://app.projectlayer.com) and the API key. - Click Save settings, then Test connection to verify.
Once connected, SupportLayer will show the number of projects it found. If the test fails, double-check the URL and API key.
Sending a ticket to ProjectLayer
On any ticket view, agents with edit permissions will see a Send to ProjectLayer card at the bottom of the page.
- Select a project from the dropdown (fetched live from ProjectLayer).
- Choose a priority (low, medium, high, or critical). The default is based on the ticket's urgency level.
- Click Send to backlog.
SupportLayer sends the ticket subject, body, and a link back to the original ticket. If the ticket has already been sent, you will see an informational message instead of a duplicate being created.
Priority mapping
The priority dropdown defaults based on the ticket's urgency:
| Ticket urgency | Default ProjectLayer priority |
|---|---|
| Critical | Critical |
| High | High |
| Medium (or unset) | Medium |
| Low | Low |
Agents can override the priority before sending.
Required permissions
To configure the integration, a user needs the integration.manage permission (granted to Administrators by default). To send tickets, the user needs the standard ticket.edit permission.
Billing
Simple per-agent pricing with no tiers, no feature gates, and your first agent always free.
Each additional agent seat costs $12/month (£10 GBP, €12 EUR, A$18 AUD, NZ$20 NZD). Every account gets the full feature set. Administrators and end users are always unlimited and free.
Manage your subscription from Account & billing in the admin sidebar. Payments are handled securely through Stripe. SupportLayer supports GBP, EUR, USD, AUD, and NZD billing currencies.
REST API
Integrate your helpdesk with external tools, automate workflows, and build custom dashboards.
All API endpoints are under the /api/v1 base path. Requests and responses use JSON. The API is stateless — every request must include an API key.
SDKs
Official client libraries make it easier to integrate with the SupportLayer API from your language of choice.
| Language | Package | Install |
|---|---|---|
| PHP | supportlayer/php-sdk | composer require supportlayer/php-sdk |
Quick example (PHP):
use SupportLayer\SupportLayerClient;
$client = new SupportLayerClient('https://www.supportlayer.app', 'sl_live_YOUR_KEY');
// List open tickets
$tickets = $client->tickets->list(['status' => 'open']);
// Create a ticket
$client->tickets->create([
'subject' => 'Login page error',
'body' => 'Users are seeing a 500 error on the login page.',
]);
See the SDK README for full documentation, error handling, and all available methods.
Postman collection
Import the official collection into Postman to try every endpoint with pre-built requests and example responses.
Download Postman collection.
After importing, set the base_url and api_key collection variables.
Quick start
- Sign in to your workspace as an administrator.
- Navigate to API keys in the admin sidebar.
- Click Generate new key, give it a name, and choose an expiration.
- Copy the key — it is only shown once.
- Use the key in the
Authorizationheader of your HTTP requests.
Authentication
All API requests require a Bearer token. Keys are scoped to a single organization.
Authorization: Bearer sl_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
All data returned by the API is automatically filtered to the key's workspace. Keys can be revoked instantly by an administrator from the portal.
Key format
API keys follow the format sl_live_ followed by 48 hex characters. The key is hashed (SHA-256) before storage — SupportLayer never stores your key in plain text. The first 16 characters are stored as a prefix for efficient lookup.
Key management
- Expiration — keys can be set to expire after 30 days, 90 days, 1 year, or never. We recommend setting an expiration and rotating keys periodically.
- Revocation — revoke a key instantly from the API keys page. Revoked keys are rejected immediately on the next request.
- Last used — the portal shows when each key was last used, helping you identify stale keys.
Rate limits
There are currently no enforced rate limits. We ask that you keep requests reasonable (under 60 requests per minute) and implement exponential backoff if you receive 429 or 503 responses.
Tickets
Create, read, update, close, assign, and escalate tickets.
List tickets
Returns tickets in your organization, ordered by most recently updated. Supports query parameters for filtering:
| Parameter | Type | Description |
|---|---|---|
search | string | Filter by subject text or ticket ID |
status | string | Filter by status key (e.g. open, closed), or overdue for SLA-breached |
assignee | string | User ID, me, or unassigned |
category | integer | Category ID |
product | integer | Product ID |
sla | string | at_risk to show tickets with SLA due within 2 hours |
Example request:
curl -H "Authorization: Bearer sl_live_YOUR_KEY" \
"https://www.supportlayer.app/api/v1/tickets?status=open&assignee=unassigned"
200 OK
{
"data": [
{
"id": 42,
"subject": "Cannot export report as PDF",
"status": { "id": 1, "key": "open", "label": "Open" },
"urgency": { "id": 3, "name": "High", "slug": "high" },
"category": { "id": 2, "name": "Bug", "slug": "bug" },
"product": { "id": 1, "name": "Dashboard", "slug": "dashboard" },
"assignee": null,
"reporter": { "id": 5, "email": "sam@example.com", "name": "Sam Kim" },
"sla_response_due_at": "2026-04-04T16:30:00+00:00",
"first_response_at": null,
"created_at": "2026-04-04T14:30:00+00:00",
"updated_at": "2026-04-04T14:30:00+00:00"
}
],
"total": 1
}
Get ticket
Returns full ticket details including body, tags, attachments, and escalation history.
200 OK — additional fields beyond list view:
{
"data": {
"id": 42,
"subject": "Cannot export report as PDF",
"body": "When I click Export on the reporting page in Safari 17...",
"status": { "id": 1, "key": "open", "label": "Open" },
"tags": [
{ "id": 1, "name": "browser-bug", "color": "#e74c3c" }
],
"attachments": [
{
"id": 7,
"filename": "screenshot.png",
"mime_type": "image/png",
"size_bytes": 245760,
"uploaded_by": { "id": 5, "email": "sam@example.com", "name": "Sam Kim" },
"created_at": "2026-04-04T14:35:00+00:00"
}
],
"escalated_at": null,
"escalated_by": null,
"sla_pause_started_at": null,
...
}
}
Create ticket
Creates a new ticket. The ticket is automatically assigned the "Open" status and SLA tracking begins.
| Field | Type | Required | Description |
|---|---|---|---|
subject | string | Yes | Ticket subject line |
body | string | Yes | Ticket description |
reporter_email | string | No | Email of the reporting user (defaults to the API key creator) |
assignee_id | integer | No | User ID to assign the ticket to |
category_id | integer | No | Category ID |
product_id | integer | No | Product ID |
urgency_id | integer | No | Urgency ID (determines SLA deadline) |
tag_ids | array | No | List of tag IDs to apply |
Example request:
curl -X POST \
-H "Authorization: Bearer sl_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"subject": "Login page returns 500 error",
"body": "Users are reporting a server error when trying to sign in...",
"urgency_id": 4,
"category_id": 2,
"tag_ids": [1, 3]
}' \
"https://www.supportlayer.app/api/v1/tickets"
201 Created — returns the full ticket object.
Update ticket
Updates one or more fields on an existing ticket. Only include the fields you want to change.
| Field | Type | Description |
|---|---|---|
subject | string | New subject |
body | string | New body text |
status_id | integer | New status (triggers SLA pause/resume logic) |
category_id | integer | null | New category (null to clear) |
product_id | integer | null | New product (null to clear) |
urgency_id | integer | New urgency (recalculates SLA deadline) |
assignee_id | integer | null | New assignee (null to unassign) |
tag_ids | array | Full replacement of tags |
Example — change status and assign:
curl -X PUT \
-H "Authorization: Bearer sl_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{ "status_id": 2, "assignee_id": 12 }' \
"https://www.supportlayer.app/api/v1/tickets/42"
Close ticket
Convenience endpoint that sets the ticket's status to "Closed". No request body required. Returns the updated ticket.
Assign ticket
| Field | Type | Description |
|---|---|---|
assignee_id | integer | null | User ID to assign, or null to unassign |
Escalate ticket
| Field | Type | Required | Description |
|---|---|---|---|
target_user_id | integer | Yes | User ID of the escalation target (must have escalation assignee permission) |
The previous assignee is recorded in the escalation history. Returns the updated ticket.
Messages
Read and create messages (replies and internal notes) on tickets.
List messages
Returns all messages on a ticket, ordered chronologically.
200 OK
{
"data": [
{
"id": 101,
"body": "I've reproduced this on Safari 17.4. Looking into it now.",
"internal": false,
"author": { "id": 12, "email": "jordan@example.com", "name": "Jordan Lee" },
"created_at": "2026-04-04T15:10:00+00:00"
},
{
"id": 102,
"body": "Root cause: missing Content-Type header on the PDF endpoint.",
"internal": true,
"author": { "id": 12, "email": "jordan@example.com", "name": "Jordan Lee" },
"created_at": "2026-04-04T15:25:00+00:00"
}
],
"total": 2
}
Create message
| Field | Type | Required | Description |
|---|---|---|---|
body | string | Yes | Message text |
internal | boolean | No | If true, the message is an internal note (not visible to end users). Defaults to false. |
Example — add a public reply:
curl -X POST \
-H "Authorization: Bearer sl_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{ "body": "This has been fixed in the latest release. Please try again." }' \
"https://www.supportlayer.app/api/v1/tickets/42/messages"
Example — add an internal note:
curl -X POST \
-H "Authorization: Bearer sl_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{ "body": "Escalating to engineering — this is a regression.", "internal": true }' \
"https://www.supportlayer.app/api/v1/tickets/42/messages"
201 Created — returns the message object. If this is the first non-internal response by someone other than the reporter, it is recorded as the first response for SLA purposes.
Lookups
Fetch workspace configuration data — statuses, categories, urgencies, tags, and products.
Use these endpoints to populate dropdowns, validate IDs before creating tickets, or sync configuration to external systems.
List statuses
200 OK
{
"data": [
{ "id": 1, "key": "open", "label": "Open", "sort_order": 0, "pauses_sla": false, "is_locked": true },
{ "id": 2, "key": "in_progress", "label": "In Progress", "sort_order": 1, "pauses_sla": false, "is_locked": true },
{ "id": 3, "key": "on_hold", "label": "On Hold", "sort_order": 2, "pauses_sla": true, "is_locked": true },
{ "id": 4, "key": "with_client", "label": "With Client", "sort_order": 3, "pauses_sla": true, "is_locked": true },
{ "id": 5, "key": "closed", "label": "Closed", "sort_order": 4, "pauses_sla": false, "is_locked": true }
]
}
List categories
Returns categories sorted by sort order. Each category includes an optional parent_id for hierarchical structures.
200 OK
{
"data": [
{ "id": 1, "name": "General", "slug": "general", "sort_order": 0, "parent_id": null },
{ "id": 2, "name": "Bug", "slug": "bug", "sort_order": 1, "parent_id": null },
{ "id": 3, "name": "Account", "slug": "account", "sort_order": 2, "parent_id": null }
]
}
List urgencies
Returns urgency levels with their SLA first-response windows.
200 OK
{
"data": [
{ "id": 1, "name": "Low", "slug": "low", "sort_order": 0, "first_response_minutes": 480 },
{ "id": 2, "name": "Normal", "slug": "normal", "sort_order": 1, "first_response_minutes": 240 },
{ "id": 3, "name": "High", "slug": "high", "sort_order": 2, "first_response_minutes": 120 },
{ "id": 4, "name": "Critical", "slug": "critical", "sort_order": 3, "first_response_minutes": 60 }
]
}
List tags
200 OK
{
"data": [
{ "id": 1, "name": "browser-bug", "color": "#e74c3c" },
{ "id": 2, "name": "feature-request", "color": "#3498db" },
{ "id": 3, "name": "urgent-escalation", "color": "#e67e22" }
]
}
List products
Returns products defined for your organization, sorted by sort order.
200 OK
{
"data": [
{ "id": 1, "name": "Dashboard", "slug": "dashboard", "sort_order": 0 },
{ "id": 2, "name": "Mobile App", "slug": "mobile-app", "sort_order": 1 },
{ "id": 3, "name": "API", "slug": "api", "sort_order": 2 }
]
}
Users
List and retrieve agents, managers, and administrators in your organization.
List users
Returns all active users in your organization.
200 OK
{
"data": [
{
"id": 1,
"email": "admin@example.com",
"first_name": "Alex",
"last_name": "Morgan",
"name": "Alex Morgan"
},
{
"id": 5,
"email": "sam@example.com",
"first_name": "Sam",
"last_name": "Kim",
"name": "Sam Kim"
}
]
}
Get user
Returns details for a single user. The user must be an active member of the API key's organization.
End Users
Manage customer accounts programmatically — provision reporters before creating tickets on their behalf.
List end users
Returns all end users in your organization.
200 OK
{
"data": [
{
"id": 5,
"email": "sam@example.com",
"first_name": "Sam",
"last_name": "Kim",
"name": "Sam Kim",
"status": "Active"
}
]
}
Create end user
Creates a new end-user account and adds them to your organization. If an account already exists for the given email, it is linked to your organization instead.
| Field | Type | Required | Description |
|---|---|---|---|
email | string | Yes | Email address for the end user |
first_name | string | Yes | First name |
last_name | string | Yes | Last name |
Example request:
curl -X POST \
-H "Authorization: Bearer sl_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"email": "sam@example.com",
"first_name": "Sam",
"last_name": "Kim"
}' \
"https://www.supportlayer.app/api/v1/end-users"
201 Created
{
"data": {
"id": 5,
"email": "sam@example.com",
"first_name": "Sam",
"last_name": "Kim",
"name": "Sam Kim"
}
}
Tip: Use this endpoint to provision a reporter before passing their email as reporter_email when creating a ticket.
Statistics
Pull the same real-time counters and analytics shown in the portal dashboard and reporting page.
Dashboard statistics
Returns the same real-time counters shown on the portal dashboard.
200 OK
{
"data": {
"open": 12,
"my_open": 4,
"unassigned": 3,
"overdue": 2,
"at_risk": 1,
"closed_today": 7
}
}
Reporting statistics
Returns the same analytics available on the reporting page, including:
- by_status — ticket counts grouped by status.
- avg_first_response_minutes — average time to first response across all responded tickets.
- sla_compliance_pct — percentage of tickets where first response was within the SLA deadline.
- by_agent — open and closed ticket counts per assigned agent.
- volume_by_day — daily ticket creation counts for the last 30 days.
200 OK
{
"data": {
"by_status": {
"open": { "label": "Open", "count": 8 },
"in_progress": { "label": "In Progress", "count": 4 },
"closed": { "label": "Closed", "count": 31 }
},
"avg_first_response_minutes": 47.3,
"sla_compliance_pct": 89.2,
"by_agent": [
{ "name": "Jordan Lee", "open": 3, "closed": 12 },
{ "name": "Morgan Chen", "open": 2, "closed": 8 }
],
"volume_by_day": {
"2026-03-06": 3,
"2026-03-07": 5,
"2026-03-08": 2
},
"total_responded": 37,
"within_sla": 33
}
}
Error handling
Standard HTTP status codes with structured JSON error bodies.
Error responses always include a JSON body with an error object:
{
"error": {
"code": "validation_error",
"message": "Field \"subject\" is required."
}
}
| Status | Code | Description |
|---|---|---|
| 401 | authentication_failed | Missing, invalid, expired, or revoked API key |
| 403 | access_denied | The API key does not have permission for this action |
| 404 | not_found | The resource does not exist or is not in your organization |
| 422 | validation_error | Missing required fields or invalid data |
| 500 | server_error | An unexpected error occurred on our end |
Best practices
- Always send
Content-Type: application/jsonfor POST/PUT/PATCH requests. - Check the HTTP status code before parsing the response body.
- Use lookup endpoints (
/statuses,/categories,/urgencies,/tags,/products) to fetch valid IDs before creating or updating tickets. - Rotate API keys periodically. Use the expiration feature and generate a replacement key before the old one expires.
- Store API keys securely — treat them like passwords. Never commit them to source control or expose them in client-side code.
Need help with an integration? Get in touch — we're happy to assist.