New to the API? Start with Authentication to create a key and make your first request, then come back here for the shared behavior.
Base URL
All requests go to your organization’s subdomain:<your-subdomain> with your organization’s slug — the subdomain you sign in on. For example, if you sign in at acme.conveyour.com, your slug is acme. Every request carries the x-conveyour-token header — see Authentication.
Team scoping
If your org has Teams enabled, most endpoints accept ateams parameter that scopes the request to one or more teams. Teams control which contacts and resources are visible, so sending the wrong scope — or none at all — changes which records you get back.
Pass teams as a query parameter on GET requests:
teams in the body instead:
string | array
One or more team IDs. Accepts a single value or an array. Read from the query string first, then from the JSON body.
Teams is a standard feature on ConveYour-enabled orgs. If your org is on a legacy program that does not use Teams, omit this parameter entirely. See Teams Introduction in the Help Center for how teams affect contact and resource visibility.
Response envelope
Every response — success or failure — uses the same three-field envelope:
Always branch on the
status field, not just the HTTP code.
Errors
Errors use the same envelope withstatus: "failed", a message, and often a data object carrying field-level validation details.
Pagination
Endpoints that paginate
Three return the full envelope, and they honourper_page — but only when you send page. Omit it and you get a bare flat array with no envelope keys at all ($page defaults to 0, and the envelope is built only if ($page > 0)):
Four return a reduced envelope — no
per_page, no has_more/has_less:
And one returns
results with no page metadata at all:
Everything else returns a flat array
29 list endpoints — including Tags, Teams, Snippets, Fields, Messages, Email templates, Groups, Lessons, Reports, Custom Objects, Links and Form submission collections — return the full set as an array whether or not you sendpage:
Contacts is limit-driven, not page-driven
GET /api/contacts decides its shape from limit, and the maximum page size is 50:
limitomitted, orlimit>= 50 -> paginated.datahascount,page,pages,results;messageis"N contacts found".limitbelow 50 -> not paginated.datahas onlyresults;messageis"success".
data.results — it never returns a bare array.
CSV export
Five endpoint families acceptformat=csv and return a CSV file instead of JSON. These are the only ones that implement it — sending format=csv anywhere else is ignored and you get the normal JSON envelope:
- Contacts —
GET /api/contacts - Custom Object Records —
GET /api/custom/records - Reports —
GET /api/reports - Message events —
GET /api/messages/events(notGET /api/messages, which has no CSV support) - Shared lesson items —
GET /api/lessons/{id}/shared/{item_uuid}(notGET /api/lessons)
GET /metrics/export always responds with a CSV file and never a JSON envelope.
Content-Disposition: attachment), not the JSON envelope. CSV export is unpaginated — it returns the full matching set.
Usage limits
Some write endpoints are metered against your plan’s quotas (contacts, teams, and similar). When a quota is exceeded, the request returns429 with an explanatory message:
This is a plan usage quota, not a per-second rate limit — retrying immediately won’t help. Upgrade the plan or free up capacity (e.g. archive contacts), then retry.
429 has three distinct causes, and they need different handling. The response tells you which one you hit:
Message sends are metered separately:
POST /api/messages returns 429 against the sms or emails quota. That check happens after validation rather than up front, because the limit depends on how many contacts the message targets.
Dates and IDs
-
IDs are not all the same type. Most resources use an internal ID: a 24-character hex string, e.g.
64a1b2c3d4e5f6a7b8c9d0e1— Tags, Snippets, Groups, Lessons, Campaigns, Triggers, Custom Objects, Custom Object Records and Form submission collections all do. These do not:Type your client’s ID fields accordingly — code that assumes a 24-character string will break on these, and code that assumes an integer will break everywhere else. -
Some resources also expose a shorter public ID (
pid) used for portal-facing and shareable links — see the public Exports and shared Reports endpoints, which are reachable with thepidalone and no token. - Timestamps are typically Unix seconds (integers) on stored records; some endpoints return ISO-8601 strings. The reference page notes the format per field.
Next steps
Authentication
Create a key and make your first request.
Liquid Syntax
Personalize messages and query data inside templates.