Offers API reference
Manage calls to action, content, link destinations, and supported provider actions through the public REST API.
Use offers to configure calls to action in a flow. Saving an offer defines what happens later on your site. It does not submit a contact or execute a provider action during the API request.
Authentication and offer operations
Paths below follow https://api.rightmessage.com/v1/{teamPid}. GET requires read or write; mutations require write. The * ability satisfies both. The shared request conventions cover bearer authentication, headers, project access, and rate limits.
| Method and path | Request | Success |
|---|---|---|
GET /offers | No filters or pagination parameters | 200, {"data":[RESOURCE]} |
GET /offers/{offer} | Resource ID from the list | 200, {"data":RESOURCE} |
POST /offers | Create body below | 201, {"data":RESOURCE} |
PUT or PATCH /offers/{offer} | Partial body below | 200, {"data":RESOURCE} |
DELETE /offers/{offer} | No body | 204, empty body |
PUT and PATCH have the same partial-update behavior. An omitted top-level field retains its value. A collection with no resources returns {"data":[]}. Reads return the draft when one exists, otherwise the stable configuration.
Errors and draft effects
The shared error contract applies. Invalid request fields return 422 with message and field-keyed errors. Full-configuration validation can return 500 instead.
Mutations save a draft, not live changes. Publishing applies the whole project draft, including edits made elsewhere. The draft contract covers snapshots, dashboard updates, and save failures.
Offer request fields
Only name is required on create. Every other field is optional, and every field is optional on update.
| Field | Type and limits | Create default |
|---|---|---|
name | Nonempty string, maximum 255 | Required |
is_enabled | Boolean | true |
parts | Object | Defaults below |
parts.title | String, maximum 500 | Untitled Offer |
parts.description | Nullable string | null |
parts.button_text | Nullable string, maximum 255 | Learn More |
parts.image_url | Nullable string, maximum 2,000 | null |
action | Object | Link action |
action.type | link, tag, event, automation, list, or contact | link |
action.settings | Object | Empty object |
The following keys belong inside action.settings.
| Key | Type and behavior |
|---|---|
url | Nullable string, maximum 2,000. Link destination. The request does not apply a URL-format rule. |
thanks_message | Nullable string at HTTP validation. For non-link actions, the stored schema requires a string when supplied. Used to seed the post-conversion message when the redirect flow has no children. |
platform | Provider-name string. |
form_ids, tag_ids | Arrays of strings. |
list_id, automation_id | Strings. |
event_name | Nonblank string. Trimmed and saved as one event name, not as a JSON list. |
redirect_url | String, maximum 2,000. Creates a root flow with one same-window redirect. |
redirectFunnel | Flow-definition object. Overrides redirect_url when both are supplied. Its nodes follow the flow definition schema. |
Saved configuration must also pass action-specific validation. Passing request validation does not guarantee that an incomplete provider action can be saved. Nested parts and action.settings updates merge their supplied keys. A supplied list replaces that list.
There is a current mapping mismatch for list_id and automation_id. The service stores singular listId and automationId, while visitor actions consume listIds and automationIds. A successful save using those arguments alone does not establish that a list subscription or automation will run.
Non-link actions receive a root redirect flow when missing. If its child list is empty, repair inserts a message using thanks_message, or Thank you! when empty. Updating thanks_message does not overwrite an existing redirect flow's content. A directly supplied redirectFunnel does not receive the flow API's node normalization: include required node fields, such as open on redirect nodes.
For tag actions, repair trims tag_ids, splits entries at commas and newlines, and drops empty entries. For list actions, it normalizes the stored plural listIds, not the singular value produced by list_id. Unknown settings do not pass through unchanged. Only recognized settings are saved, so sending listIds directly is not a workaround through this endpoint.
Offer responses and classification limits
The resource contains id, name, is_enabled, parts, and action. parts returns title, description, button_text, and image_url. action returns type plus settings containing only url, thanks_message, platform, and tag_ids. Missing settings appear as null.
The serializer does not echo form_ids, list_id, automation_id, event_name, or redirects. Their absence from a response is not evidence that the server discarded them.
There is a production classification mismatch. The offers list includes link actions only. Item GET, update, and delete reject only the exact action type form. A non-link action created here can therefore disappear from the offers list while remaining accessible by its offer ID. Keep the ID returned by create. The forms API describes the corresponding list behavior.
Deleting an offer clears its offerId from matching offer nodes in flows. The flow node remains in the draft.
Illustrative requests and responses
These illustrative examples use the fictional WorkForge project. The same resource schema covers every CRUD response.
The PATCH example also works with PUT. The create, item-read, and update envelopes have this shape. The list places these resource objects in its data array. An update returns the updated values. DELETE returns no JSON.