# Forms API reference

Manage form content, provider settings, fields, and draft lifecycle through the public REST API.

Available on the Scale and Pro plans.

Use forms to collect contact details in flows. These endpoints save form configuration. They don't submit a contact or send data to an email platform.

## Authentication and form 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](https://rightmessage.com/help/rest-api-overview#base-url-and-authentication) cover bearer authentication, headers, project access, and rate limits.

| Method and path              | Request                             | Success                    |
| ---------------------------- | ----------------------------------- | -------------------------- |
| GET `/forms`                 | No filters or pagination parameters | 200, `{"data":[RESOURCE]}` |
| GET `/forms/{form}`          | Resource ID from the list           | 200, `{"data":RESOURCE}`   |
| POST `/forms`                | Create body below                   | 201, `{"data":RESOURCE}`   |
| PUT or PATCH `/forms/{form}` | Partial body below                  | 200, `{"data":RESOURCE}`   |
| DELETE `/forms/{form}`       | 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](https://rightmessage.com/help/rest-api-overview#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](https://rightmessage.com/help/rest-api-publishing) applies the whole project draft, including edits made elsewhere. The [draft contract](https://rightmessage.com/help/rest-api-overview#draft-and-live-configuration) covers snapshots, dashboard updates, and save failures.

## Form request fields

Only `name` is required on create. All fields are optional on update.

| Field                                   | Type and validation                                                                        | Create default                                      |
| --------------------------------------- | ------------------------------------------------------------------------------------------ | --------------------------------------------------- |
| `name`                                  | Nonempty string, maximum 255                                                               | Required                                            |
| `is_enabled`                            | Boolean                                                                                    | true                                                |
| `parts`                                 | Object                                                                                     | Defaults below                                      |
| `parts.title`                           | String, maximum 500                                                                        | Untitled Form                                       |
| `parts.description`                     | Nullable string                                                                            | null                                                |
| `parts.button_text`                     | Nullable string, maximum 255                                                               | Submit                                              |
| `action`                                | Object                                                                                     | Form action                                         |
| `action.settings`                       | Object                                                                                     | Default fields and visible labels                   |
| `action.settings.platform`              | Provider-name string                                                                       | Unset                                               |
| `action.settings.event_name`            | Nonblank string, trimmed and stored as one event name                                      | Unset                                               |
| `action.settings.form_ids`              | Array. The request has no item-level rule; repair normalizes form-action IDs into strings. | \[] after repair                                    |
| `action.settings.fields`                | Array of field objects                                                                     | Email and submit fields                             |
| `action.settings.fields[].display_type` | Required string for each supplied field                                                    | No default on supplied fields                       |
| `action.settings.fields[].label`        | String, maximum 255                                                                        | Supplied placeholder, or empty string, after repair |
| `action.settings.fields[].width`        | Integer, 1 through 6                                                                       | 6 after repair                                      |

The default email field has `label: "Email address"`, `placeholder: "Your email address"`, `displayType: "email"`, `width: 6`, and `options: {}`. The default submit field starts with `displayType: "submit"`, `width: 6`, and `options: {}`; configuration repair also fills its `placeholder` and `label` with empty strings.

Nested objects are not closed allowlists. The service also recognizes `parts.image_url`; `action.type`; and settings `url`, `thanks_message`, `tag_ids`, `list_id`, `automation_id`, `show_labels`, `redirect_url`, and `redirectFunnel`. Those keys lack dedicated rules in the forms HTTP validator. Their stored representation still undergoes configuration validation. Use the [offers settings contract](https://rightmessage.com/help/rest-api-offers) for their mapping. `show_labels` maps to `formSettings.showLabels`; `redirectFunnel` takes precedence over `redirect_url`.

The shared mapper currently stores singular list and automation identifiers, while visitor actions expect plural keys. As explained in the offers reference, saving `list_id` or `automation_id` alone does not establish a working provider action.

Field objects preserve additional keys. Write-side `display_type`, `question_id`, and `question_display` become `displayType`, `segmentGroupId`, and `questionDisplay`. This CRUD path does not validate referenced question fields separately.

Nested `parts`, `action`, and `action.settings` merge by supplied key. A supplied `fields` array replaces the list before configuration repair. Repair then adds an email field and a submit field if either is missing, so `fields: []` restores those 2 fields rather than producing an empty form. It fills omitted field widths with 6, caps widths at 6, supplies empty options and placeholders, and defaults an omitted label to its placeholder.

For form actions, repair trims and splits `form_ids` strings at commas and newlines, removes empty entries, and also converts integer entries to strings. Omitted IDs become `[]`. A non-link action gets a redirect flow when one is absent; an empty redirect flow gains a message node using `thanks_message`, or `Thank you!` when that value is empty. Changing `thanks_message` later does not replace an existing nonempty redirect flow.

## Form responses and classification limits

The response contains `id`, `name`, `is_enabled`, `parts`, and `action`. `parts` contains `title`, `description`, `button_text`, and `image_url`. `action.type` is always serialized as `form`. Its `settings` contains `platform`, `form_ids`, `thanks_message`, `fields`, and `show_labels`. Field objects use stored camelCase keys, not the write-side snake\_case aliases. Settings not named here are not echoed.

The forms list includes every non-link action, including tag, event, list, automation, and contact actions. Item GET, update, and delete accept only the exact stored action type `form`. A listed non-form action can therefore return 404 at its forms item URL. This is a production inconsistency, not a missing permission. Its offer item URL can still be usable.

Deleting a form clears matching `offerId` references in flow nodes. It does not delete the flow nodes or previously collected contacts.

## Illustrative requests and responses

These illustrative examples use the fictional WorkForge project. The same resource schema covers every CRUD response.

```http
GET /v1/123456/forms HTTP/1.1
Host: api.rightmessage.com
Authorization: Bearer YOUR_API_TOKEN
Accept: application/json

GET /v1/123456/forms/ofr_example2 HTTP/1.1
Host: api.rightmessage.com
Authorization: Bearer YOUR_API_TOKEN
Accept: application/json

POST /v1/123456/forms HTTP/1.1
Host: api.rightmessage.com
Authorization: Bearer YOUR_API_TOKEN
Content-Type: application/json
Accept: application/json

{
	"name": "WorkForge updates",
	"parts": {
		"title": "Get WorkForge updates"
	}
}

PATCH /v1/123456/forms/ofr_example2 HTTP/1.1
Host: api.rightmessage.com
Authorization: Bearer YOUR_API_TOKEN
Content-Type: application/json
Accept: application/json

{
	"name": "WorkForge updated"
}

DELETE /v1/123456/forms/ofr_example2 HTTP/1.1
Host: api.rightmessage.com
Authorization: Bearer YOUR_API_TOKEN
Accept: application/json
```

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.

```json
{
	"data": {
		"id": "ofr_example2",
		"name": "WorkForge updates",
		"is_enabled": true,
		"parts": {
			"title": "Get WorkForge updates",
			"description": null,
			"button_text": "Submit",
			"image_url": null
		},
		"action": {
			"type": "form",
			"settings": {
				"platform": null,
				"form_ids": [],
				"thanks_message": null,
				"fields": [
					{
						"label": "Email address",
						"placeholder": "Your email address",
						"displayType": "email",
						"width": 6,
						"options": {}
					},
					{
						"displayType": "submit",
						"width": 6,
						"options": {},
						"placeholder": "",
						"label": ""
					}
				],
				"show_labels": true
			}
		}
	}
}
```
