REST API authentication and request conventions
Reference for REST authentication, the OpenAPI document, project identifiers, abilities, response envelopes, limits, errors, and drafts.
The public REST API reads project configuration and analytics, saves configuration drafts, starts exports, and publishes a project. It is distinct from the dashboard's session API and the hosted MCP connection.
Base URL and authentication
The base URL is https://api.rightmessage.com/v1. Authenticate with an API token in Authorization: Bearer YOUR_API_TOKEN. Send Accept: application/json; JSON bodies also use Content-Type: application/json.
The API accepts only API tokens. Tokens your AI assistant gets through hosted OAuth work only with the MCP server, and this API rejects them.
The API token setup guide explains how to create your first token in the dashboard, under Your account > API & AI access > API tokens. Only a signed-in dashboard session can create or revoke tokens; an API token can't.
Project endpoints use /{teamPid}/.... This is the public project identifier, not its name or an internal database ID. Resource IDs come from responses and are scoped to the chosen project's configuration. Use the returned strings unchanged.
A token belongs to a user, not one project. Project members and administrators can access project routes. Ordinary API mutations do not require the owner role. Nonmembers receive 403. An unknown project receives 404.
Token creation requires API access on the account. Project endpoints do not repeat that token-creation entitlement check. Subscription and publication requirements remain separate from token abilities. See token creation and its plan requirement.
OpenAPI reference
The complete machine-readable reference is an OpenAPI 3.1 document at https://api.rightmessage.com/openapi.json (opens in a new tab). Import it into an API client, generate a typed client from it, or give it to an AI coding assistant. It's public: you don't need a token to download it, and any website can fetch it.
| What it includes | Detail |
|---|---|
Every /v1 endpoint | Path, method, parameters, request body, and response shapes. {teamPid} is the project ID. |
| Operation IDs | Stable {resource}.{action} names, such as flow.index or apiToken.store. |
| Summaries | A one-line summary and description for each operation, grouped by tags such as Flows and Exports. |
| Token abilities | The abilities an operation accepts, in x-rightmessage-abilities. An empty list means any token for the account works, except on operations marked x-rightmessage-session-only (creating and revoking tokens), which refuse every API token. |
| Error responses | The 401 and 429 responses on every operation, plus endpoint-specific validation and not-found errors. |
The document is cached for up to an hour and sends an ETag, so clients can check for changes cheaply. The tables in these REST API articles explain behavior the schema can't, such as draft handling and plan requirements.
Illustrative authenticated request
This illustrative request reads flows from the fictional WorkForge project.
Abilities and their limits
Each token has a list of abilities. Tokens created on the API & AI access page have *.
| Ability | Project-route access |
|---|---|
read | Configuration, analytics, data, and export status/download GET routes |
write | Those GET routes plus configuration create/update/delete and starting exports |
publish | The publish operation; it does not by itself grant the GET or CRUD routes |
* | All ability checks |
Read routes accept either read or write. A token without the ability a project route needs gets 403 with {"message":"Invalid ability provided."}. Omitted abilities on token creation default to ["*"]. An explicitly empty abilities array remains empty, so that token is refused wherever an ability is needed.
The same abilities apply everywhere a token works, not just on these routes:
GET /oauth-connectionsneedsreadorwrite, andDELETE /oauth-connections/{clientId}needswrite.GET /tokensaccepts any token. Creating and revoking tokens refuses every token, so a leaked token can't make a broader one.- The dashboard API under
/api, such as the media library routes, judges a token by request method: GET needsreadorwrite, and every other method needswrite. - The hosted MCP server shows a token only the tools its abilities allow. See API token abilities in MCP.
Outside /v1/{teamPid}, a refusal is 403 with a message naming the missing ability, such as This API token can't make changes: it needs the `write` ability. Create a token with it under Your account › API & AI access. Abilities don't restrict which projects a token reaches: it reaches every project its user can. Signed-in dashboard sessions and OAuth-connected AI assistants aren't limited by abilities.
Tokens and OAuth connections documents the exact management operations.
Rate limits
User-scoped token and OAuth management routes allow 60 requests per minute. Project routes allow 120 requests per minute. These are route limits, not independent quotas for every resource or token. Excess requests return 429. The response exposes remaining-limit information and a retry interval when throttled.
These limits do not apply by inheritance to the separate /api media and template catalog routes. See media library and template catalog API. There's no REST resource for Pages; AI assistants manage them with the Pages MCP tools.
JSON and validation
Request names are case-sensitive. Most v1 resource fields use snake_case, while flow definitions and nested design/input settings retain documented camelCase names.
Optional means a field can be omitted. Nullable means request validation accepts an explicit JSON null, though stored-configuration validation may still reject it. Boolean request fields accept booleans, 0, 1, "0", and "1" without converting their types. Use JSON booleans and numbers for stored boolean and numeric fields. A field described as array can represent an object or a list. Follow the documented shape.
Undocumented top-level fields are not part of the write contract. Some nested objects accept additional keys, but mapping and full-configuration validation determine whether those keys survive. An accepted request shape does not guarantee a valid flow, campaign, or widget configuration.
Success envelopes
| Operation | Typical contract |
|---|---|
| List a configuration resource | 200, {"data":[RESOURCE]}; no pagination |
| Read or update one resource | 200, {"data":RESOURCE} |
| Create a configuration resource | 201, {"data":RESOURCE} |
| Delete a configuration resource | 204, no body |
| Start an export | 202, {"data":{"job_id":"...","status":"processing","message":"Export started."}} |
| Read analytics or project data | 200, {"data":...}; payload differs by endpoint |
| Publish | 200, top-level message and published_at, without a data envelope |
Do not assume every response has data. Errors, publication responses, and dashboard media endpoints use other shapes.
Error contract
API errors are always JSON, whatever the Accept header. Most bodies have a message describing the problem, and validation failures add errors.
| Status | Meaning and body |
|---|---|
| 401 | The token is missing, invalid, or revoked. The message asks you to send an API token as Authorization: Bearer <token>. The WWW-Authenticate header is Bearer realm="rightmessage-api", plus error="invalid_token" when a token was sent but rejected. |
| 403 | Membership, ability, entitlement, or suspension check failed. Usually message. Project suspension adds code: "project_suspended"; account suspension adds code: "account_suspended". |
| 404 | Project or item not found, or not owned by the requested scope. Usually message; exports have endpoint-specific bodies. A path that matches no endpoint returns a message naming the method and path, with a pointer to the OpenAPI reference. |
| 409 | Conflict: publication activation is busy, an export is not complete, or the draft kept changing while a configuration write was being saved. The draft case returns {"message":"The draft changed while this change was being saved, so nothing was saved. Read the draft again and retry."}; nothing was saved, so read the draft again and resend the change. Other bodies are endpoint-specific. |
| 422 | Request validation failure with message and errors, a map of field paths to message arrays. Active question-test locks can use errors.config. Publish-without-draft has only message. |
| 429 | Route rate limit exceeded. |
| 500 | Unhandled service failure. Full-configuration schema failures can reach this status rather than 422. Do not depend on debug exception details being exposed. |
| 503 | Maintenance or reporting unavailable. Maintenance returns error: "maintenance", message, and nullable estimatedEnd. Reporting errors differ by endpoint. |
Authenticated users can send GET requests to the demo project. Demo mutations return 403. A request from a suspended account invalidates its presented API token and session.
Illustrative validation response:
Draft and live configuration
Configuration CRUD reads the draft first, then stable configuration. Mutations save a draft and a snapshot of the previous configuration, and notify open dashboards. They do not change the published snippet by themselves.
Saving includes configuration repair before schema validation. The saved response can therefore contain defaults absent from the request, including question Other labels, form fields, and widget design settings. Validation covers the whole configuration, not just the edited resource. A failed mutation can leave a snapshot or a newly created draft behind; an error is not a transaction-level promise that nothing changed.
Active question A/B tests protect wording, answers, display, behavior, and linked Auto-Segment rules at the configuration save boundary. Such a change can return 422 under errors.config, including through a segment-group update or deletion. Sync mappings, internal names, and flow membership remain editable. This is separate from the token's write ability.
A request to a project you belong to can switch your current project to the one in the URL. Account-level entitlement checks then use that project.
PUT and PATCH are both partial updates at the top level. Nested merge and replacement rules differ by resource. In particular, a campaign's supplied changes list and a flow's supplied definition can remove content omitted from the payload.
Publishing applies the entire project draft, not just changes made by the current token, and publishes pending Pages changes with it. Analytics describe recorded activity, not draft previews. Project data endpoints have different draft and live sources.