value (what you submit elsewhere in the API) and a label (what you show), plus a few extra keys per resource.
All of them use the X-Sender-Tenant + X-API-Key headers. All except GET /public/templates/:id/merge-fields return the standard pagination envelope.
Endpoints at a glance
“Paged in memory” means the full set is loaded, then
limit and offset are
applied to it. total is still the true count, and has_more and
next_cursor behave exactly as on the database-paged endpoints. These sets
are small by nature, so paging them is rarely necessary.Templates
integer
default:"50"
Page size. Range 1 to 100.
integer
default:"0"
Records to skip. Minimum 0.
string
Filter by channel. One of
email, sms, push. Any other value returns
400.string
Template UUID. This is the id you pass as
templateId elsewhere in the API.string
Template name.
string
email, sms or push.string[]
Merge tag keys found in this template, sorted and de-duplicated. Extracted
from the subject line, the HTML body, the SMS body, the block document and
the template metadata by scanning for
{{key}} and {{key|fallback}}.This list is the workspace’s template library. Archived templates and
templates created inside a campaign or automation are excluded, so a template
a user can see in a campaign editor may not appear here. It is still readable
by id.
Template merge fields
string
required
Template UUID. A non-UUID value returns
400.string[]
Merge tag keys, sorted and de-duplicated.
mergeFields misses, notably ones that live only in the push payload or in template settings. Use the list for a quick preview and this route when you need the authoritative set for one template.
Campaigns
integer
default:"25"
Page size. Range 1 to 200. Note this is not the 50/100 used by the other
endpoints here.
integer
default:"1"
1-based page number. Minimum 1.
integer
Records to skip. Minimum 0. When present it wins over
page. The
response carries offset, never page.string
Single status filter. One of
draft, scheduled, sending, sent,
paused, cancelled, failed.string
Comma-separated list of the same statuses, for a multi-select. When present it
replaces
status.string
One of
email, sms. Campaigns have no push channel.string
Case-insensitive substring match on the campaign name. Max 255 characters.
string
Sort key, max 64 characters. Sortable columns are
createdAt, updatedAt,
name, scheduleAt, sentAt. Prefix with - for descending
(-createdAt), or use column:asc / column:desc. An unrecognised value
falls back to updatedAt descending rather than erroring.string
UUID. Only campaigns targeting that segment.
string
Comma-separated UUID list. Only campaigns carrying at least one of those tags.
boolean
default:"false"
true returns archived campaigns instead of live ones. Accepts true,
false, 1, 0.boolean
true returns only campaigns with more than one variant, false only
single-variant campaigns. Omit for both.string
Campaign UUID.
string
Campaign name.
string
email or sms.string
draft, scheduled, sending, sent, paused, cancelled or failed.Custom fields
integer
default:"50"
Page size. Range 1 to 100.
integer
default:"0"
Records to skip. Minimum 0.
string
Custom field UUID.
string
The field’s human label, as set in the app.
string
The field’s stable key. This is what you write into a profile’s
customProperties, not value.string
Value type. One of
text, number, date, boolean, select,
multiSelect, url, list.string[] | null
Allowed values for a
select or multiSelect field. null for every other
kind.object[]
The same values pre-shaped as
{ label, value } for a select control. Always
an array, empty when the field has no options.Sender addresses
POST /public/messages/email will accept. The list is filtered to addresses whose domain is verified and whose inbox verification has completed, so anything returned here is safe to send from. A pending or failed inbox, or an address on an unverified domain, is omitted entirely.
integer
default:"50"
Page size. Range 1 to 100.
integer
default:"0"
Records to skip. Minimum 0.
string
The email address. Pass this as
fromEmail.string
Name <email> when the address has a From name set, otherwise just the
address.string | null
The configured From name, or
null.SMS sender IDs
POST /public/messages/sms and POST /otp/send will accept. Only approved and active sender IDs are returned. A pending or rejected request is omitted, so an id you can see in the app may not appear here yet.
integer
default:"50"
Page size. Range 1 to 100.
integer
default:"0"
Records to skip. Minimum 0.
string
The sender ID string. Pass this as
senderId.string
Same as
value.Tags
integer
default:"50"
Page size. Range 1 to 100.
integer
default:"0"
Records to skip. Minimum 0.
string
The tag name. This is what profile and campaign payloads carry.
string
Same as
value.string
Tag UUID, for the endpoints that filter by tag id such as
GET /public/campaigns?tagIds=.string | null
Display colour. One of
neutral, primary, accent, warn, danger,
info, violet, or null when unset.value is the tag name and id is its UUID. That split is deliberate:
profile payloads carry tag names, while campaign filtering carries tag ids.Create a tag
string
required
Tag name. Non-empty, max 60 characters. Leading and trailing whitespace is
trimmed before the uniqueness check.
string
One of
neutral, primary, accent, warn, danger, info, violet.
Omit for no colour. Any other value returns 400.201 with the created tag.
string
Tag UUID.
string
The trimmed name.
string | null
The colour, or
null.string
ISO 8601 timestamp.
string
ISO 8601 timestamp.
409
Events
integer
default:"50"
Page size. Range 1 to 100. The full catalog is larger than the default page,
so raise this or page through it.
integer
default:"0"
Records to skip. Minimum 0.
string
The event key. For a system event this is the value you pass in a webhook
subscription’s
events array. For a custom event it is the event name you
send to event ingest.string
Display name. Equal to
value for a system event; the workspace’s own
display name for a custom event.string
system for a built-in webhook event, custom_event for one observed in
this workspace.object[]
Present on custom events only. The properties seen or declared on that event,
so a picker can offer them without a second call.
Only active custom events are listed. A custom event that has been
retired in the app disappears from this list even though its historical data
remains. A system event is always listed whether or not this workspace has
ever produced one.
Send a message
Where
fromEmail and senderId from this page are used.Webhooks
Subscribe to the system events listed above.
Pagination
The
limit, offset, has_more and next_cursor contract.Errors
Status codes, the error envelope and rate limits.

