Reference
Endpoints
Every route under https://solvey.io/api/v1. Authentication, errors and the rate limit are on Getting started; how webhooks behave is on Webhooks.
Me
The first call to make with a new key: who it is, and what it may do.
GET/meread
The key, its scope, and the person it acts as.
curl https://solvey.io/api/v1/me \ -H "Authorization: Bearer sk_live_…"
{ "data": { "tenantId": "…", "key": { "id": "…", "name": "Zapier", "prefix": "sk_live_ab12cd", "scope": "read_write" }, "actor": { "id": "…", "role": "admin" } } }Tickets
Everything the console's queue and ticket page can do. Wherever a path says {id}, pass either the ticket's uuid or its human key such as SLV-1043.
GET/ticketsread
List tickets, newest first, with filters and paging.
| Query | |
|---|---|
status | Status slugs (see /statuses). Repeat or comma-separate for any-of. |
priority | low, normal, high, urgent. Repeat or comma-separate. |
assigneeId | User ids, and/or the word unassigned. |
tag | One tag. |
limit | 1–100, default 25. |
offset | Default 0. |
curl https://solvey.io/api/v1/tickets?status=open,pending&priority=high&assigneeId=unassigned&limit=25 \ -H "Authorization: Bearer sk_live_…"
{ "data": [ {
"id": "01a0…", "key": "SLV-1043", "source": "api",
"subject": "Printer on floor 3 jams", "status": "open", "statusLabel": "Open",
"priority": "high", "tags": ["printer"],
"requester": { "id": "…", "name": "Dana Ortiz", "email": "dana@example.com" },
"assignee": null,
"sla": { "enabled": true, "firstResponse": { "phase": "on_track", "fillPercent": 12, "…": "…" }, "resolution": { "…": "…" } },
"createdAt": "2026-09-05T11:28:03.702Z", "updatedAt": "2026-09-05T11:28:03.702Z"
} ], "page": { "total": 42, "limit": 25, "offset": 0 } }A key whose creator lacks view_all_tickets sees only their own tickets, as in the console.
POST/ticketsread_write
Create a ticket. Answers 201 with the ticket; source is api.
| Body | |
|---|---|
subject | Required, up to 200 characters. |
description | Required, up to 20,000 characters. |
priority | low, normal (default), high, urgent. |
tags | Up to 20 tags. |
requesterId | Who the ticket is for; defaults to the key's creator. |
assigneeId | A team member's id. |
customFields | Object of field id → value, e.g. { "<fieldId>": "value" }. |
curl https://solvey.io/api/v1/tickets \
-H "Authorization: Bearer sk_live_…"
-H "Content-Type: application/json" \
-d '{ "subject": "Printer on floor 3 jams", "description": "Every second page.", "priority": "high", "tags": ["printer"] }'{ "data": {
"id": "01a0…", "key": "SLV-1043", "source": "api",
"subject": "Printer on floor 3 jams", "status": "open", "statusLabel": "Open",
"priority": "high", "tags": ["printer"],
"requester": { "id": "…", "name": "Dana Ortiz", "email": "dana@example.com" },
"assignee": null,
"sla": { "enabled": true, "firstResponse": { "phase": "on_track", "fillPercent": 12, "…": "…" }, "resolution": { "…": "…" } },
"createdAt": "2026-09-05T11:28:03.702Z", "updatedAt": "2026-09-05T11:28:03.702Z"
} }GET/tickets/{id}read
One ticket in full: fields, description, custom fields, comments, events, merge links.
curl https://solvey.io/api/v1/tickets/SLV-1043 \ -H "Authorization: Bearer sk_live_…"
{ "data": { …ticket…, "description": "Every second page.", "customFields": [ … ], "comments": [ … ], "events": [ … ], "mergedInto": null, "mergedFrom": [] } }PATCH/tickets/{id}read_write
Change any of subject, description, status, priority, assigneeId, tags, customFields.
| Body | |
|---|---|
status | A status slug. |
assigneeId | A user id, or null to unassign. |
tags | The whole list; it replaces the old one. |
curl https://solvey.io/api/v1/tickets/SLV-1043 \
-H "Authorization: Bearer sk_live_…"
-H "Content-Type: application/json" \
-X PATCH -d '{ "status": "work_in_progress", "assigneeId": "…" }'{ "data": { …ticket… } }Every change appends to the ticket's event log; the answer is the ticket after the change.
GET/tickets/{id}/commentsread
The thread the key's creator may see.
curl https://solvey.io/api/v1/tickets/SLV-1043/comments \ -H "Authorization: Bearer sk_live_…"
{ "data": [ { "id": "…", "kind": "public", "body": "Fixed tomorrow.", "author": { … }, "createdAt": "…" } ] }POST/tickets/{id}/commentsread_write
Post a public reply or an internal note. Answers 201 with the ticket.
| Body | |
|---|---|
body | Required. |
kind | public — the requester sees it; internal — never leaves the organization. |
curl https://solvey.io/api/v1/tickets/SLV-1043/comments \
-H "Authorization: Bearer sk_live_…"
-H "Content-Type: application/json" \
-d '{ "body": "Fixed tomorrow.", "kind": "public" }'{ "data": { …ticket with the new comment… } }POST/tickets/{id}/mergeread_write
Mark {id} as a duplicate of another ticket. Link-only: both histories stay.
| Body | |
|---|---|
target | The survivor, as uuid or human key. targetId is accepted too. |
curl https://solvey.io/api/v1/tickets/SLV-1043/merge \
-H "Authorization: Bearer sk_live_…"
-H "Content-Type: application/json" \
-d '{ "target": "SLV-1042" }'{ "data": { …the duplicate, with mergedInto set… } }Users, tags, statuses
The vocabulary around tickets. Read-only: people join through invitations in the console, tags are created by using them, statuses are defined by admins.
GET/usersread
Everyone in the organization with their role.
curl https://solvey.io/api/v1/users \ -H "Authorization: Bearer sk_live_…"
{ "data": [ { "id": "…", "name": "Sam Lee", "email": "sam@example.com", "role": "agent", "joinedAt": "…" } ] }GET/tagsread
Tags in use, sorted.
curl https://solvey.io/api/v1/tags \ -H "Authorization: Bearer sk_live_…"
{ "data": ["printer", "vpn"] }GET/statusesread
The organization's statuses — the slugs status accepts.
curl https://solvey.io/api/v1/statuses \ -H "Authorization: Bearer sk_live_…"
{ "data": [ { "slug": "open", "label": "Open", "isTerminal": false, "slaClockRunning": true, "sortOrder": 0 } ] }Add-ons
Optional features, on or off per organization — the requester portal, ticket merge, webhooks, and the assistant's doors as they ship. Everything listed is included in the plan.
GET/addonsread
Every add-on with its state.
curl https://solvey.io/api/v1/addons \ -H "Authorization: Bearer sk_live_…"
{ "data": [ { "id": "webhooks", "label": "Webhooks", "category": "Integrations", "description": "…", "status": "available", "price": "Included", "enabled": true }, { "id": "assistant.triage", "status": "coming_soon", "enabled": false, "…": "…" } ] }A feature whose add-on is off answers 403 addon_disabled on the routes that need it.
PATCH/addons/{id}read_write
Turn an add-on on or off (admin). Add-ons marked coming_soon cannot be turned on yet.
curl https://solvey.io/api/v1/addons/SLV-1043 \
-H "Authorization: Bearer sk_live_…"
-H "Content-Type: application/json" \
-X PATCH -d '{ "enabled": false }'{ "data": { "id": "webhooks", "enabled": false } }Billing
Where the organization stands: seats bought and in use, the monthly quote, trial and period dates. Subscribing happens in the console (Paddle's checkout); changing seats, cancelling and resuming are here too.
GET/billingread
The billing summary.
curl https://solvey.io/api/v1/billing \ -H "Authorization: Bearer sk_live_…"
{ "data": { "phase": "active", "status": "active", "writable": true, "seatsInUse": 4, "seatsPurchased": 6, "seatsUnused": 2, "overSeats": false, "quote": { "totalCents": 5800, "breakdown": [ … ] }, "trialEndsAt": "…", "currentPeriodEnd": "…", "cancelAt": null, "hasSubscription": true } }phase is one of trial, trial_expired, active, past_due, canceled. When writable is false the organization can read and export but not change anything — every write answers 402 billing_locked.
Admins, agents and assistants hold seats; requesters are free. While subscribed, team invitations and promotions stop at seatsPurchased and answer 409 seats_exhausted. The trial has no cap.
POST/billing/seatsread_write
Change the purchased seats. Up is charged now, pro rata; down is credited now. Never below the people holding a seat.
| Body | |
|---|---|
seats | A whole number, at least the people holding a seat today. |
curl https://solvey.io/api/v1/billing/seats \
-H "Authorization: Bearer sk_live_…"
-H "Content-Type: application/json" \
-d '{ "seats": 8 }'POST/billing/cancelread_write
Cancel at the end of the paid period. The team keeps what it paid for; cancelAt says when.
curl https://solvey.io/api/v1/billing/cancel \ -H "Authorization: Bearer sk_live_…" -X POST
POST/billing/resumeread_write
Undo a scheduled cancellation.
curl https://solvey.io/api/v1/billing/resume \ -H "Authorization: Bearer sk_live_…" -X POST
POST/billing/portalread_write
A short-lived link to Paddle's customer portal: card, invoices, receipts.
curl https://solvey.io/api/v1/billing/portal \ -H "Authorization: Bearer sk_live_…" -X POST
{ "data": { "url": "https://customer-portal.paddle.com/…" } }Webhooks
Manage subscriptions and read the delivery log. The how-it-works — events, signatures, retries — is on the Webhooks page.
GET/webhooksread
Subscriptions.
curl https://solvey.io/api/v1/webhooks \ -H "Authorization: Bearer sk_live_…"
POST/webhooksread_write
Subscribe a URL to events. The signing secret is in this answer and nowhere else.
| Body | |
|---|---|
url | http:// or https://. |
events | One or more event types. |
description | Optional. |
curl https://solvey.io/api/v1/webhooks \
-H "Authorization: Bearer sk_live_…"
-H "Content-Type: application/json" \
-d '{ "url": "https://example.com/hooks/solvey", "events": ["ticket.created", "ticket.replied"] }'{ "data": { "id": "…", "url": "…", "events": [ … ], "active": true, … }, "secret": "whsec_…" }GET/webhooks/{id}read
One subscription.
curl https://solvey.io/api/v1/webhooks/SLV-1043 \ -H "Authorization: Bearer sk_live_…"
PATCH/webhooks/{id}read_write
Change url, description, events, or active (pause with false).
curl https://solvey.io/api/v1/webhooks/SLV-1043 \
-H "Authorization: Bearer sk_live_…"
-H "Content-Type: application/json" \
-X PATCH -d '{ "active": false }'DELETE/webhooks/{id}read_write
Delete the subscription and its delivery log. Answers 204.
curl https://solvey.io/api/v1/webhooks/SLV-1043 \ -H "Authorization: Bearer sk_live_…" -X DELETE
GET/webhooks/{id}/deliveriesread
The delivery log, newest first.
| Query | |
|---|---|
limit | Default 50, up to 200. |
curl https://solvey.io/api/v1/webhooks/SLV-1043/deliveries \ -H "Authorization: Bearer sk_live_…"
{ "data": [ { "id": "…", "eventType": "ticket.created", "status": "succeeded", "attemptCount": 1, "lastStatusCode": 200, "lastError": null, "completedAt": "…", "createdAt": "…" } ] }GET/webhooks/deliveries/{deliveryId}read
One delivery with its payload and every attempt.
curl https://solvey.io/api/v1/webhooks/deliveries/01a0… \ -H "Authorization: Bearer sk_live_…"
POST/webhooks/deliveries/{deliveryId}/redeliverread_write
Queue the same payload again. Answers 202.
curl https://solvey.io/api/v1/webhooks/deliveries/01a0…/redeliver \ -H "Authorization: Bearer sk_live_…" -X POST