Reference
REST API
The markercrm/v2 REST namespace — authentication, the response envelope, errors, pagination and every endpoint.
# REST API The Marker CRM admin is a single-page app that talks to its own REST API. You can use the same API from your add-on's admin screens, or from outside WordPress. **Base URL:** `/wp-json/markercrm/v2/` — or `rest_url('markercrm/v2/…')` in PHP. :::note This is the API the admin uses, not a separate public API. Response fields not described on this page may change between versions. From PHP inside WordPress, call the services and hooks instead. ::: ## Authentication Every endpoint except the few under `public/` needs a signed-in WordPress user who has access to the CRM. Marker CRM has no API keys of its own; it accepts whatever WordPress authenticates for its REST API. **From the WordPress admin** (your add-on's own screen), send the logged-in cookie with a `wp_rest` nonce: ```js // Enqueue your script with 'wp-api-fetch' as a dependency; it sends the nonce for you. const response = await wp.apiFetch({path: '/markercrm/v2/contacts?per_page=10'}); ``` With plain `fetch`, send a nonce made by `wp_create_nonce('wp_rest')` in the `X-WP-Nonce` header, with `credentials: 'same-origin'`. **From outside WordPress**, use an [application password](https://make.wordpress.org/core/2020/11/05/application-passwords-integration-guide/) for a user with CRM access, over HTTPS: ```bash curl -u "jane:abcd efgh ijkl mnop qrst uvwx" https://example.com/wp-json/markercrm/v2/contacts ``` ### Who may do what A user has access to the CRM when they are an administrator (`manage_options`) or have been given at least one Marker CRM permission on **Settings → Permissions**. Inside, each endpoint checks a capability named `marker_crm_{action}_{resource}`: | Resource | Actions | |---|---| | `contacts` | `view` `edit` `delete` `import` `export` | | `companies` | `view` `edit` `delete` `import` `export` (companies module on) | | `segments` (tags, lists and segments) | `view` `edit` `delete` | | `fields` (custom fields) | `view` `edit` `delete` | | `campaigns` (campaigns and templates) | `view` `edit` `delete` `send` | | `automations` | `view` `edit` `delete` | | `logs` | `view` `delete` | | `reports` | `view` | | `dashboard` | `manage` | | `settings` | `manage` | `edit` implies `view`; `delete`, `import` and `send` imply `edit`; `export` implies `view`. Administrators hold every capability. Add-ons can add resources through `marker_crm/capabilities`. ## Requests - Send JSON bodies with `Content-Type: application/json`. - `PUT` and `DELETE` also work as a `POST` with an `X-HTTP-Method-Override` header, which is what the admin does. - Arrays in a query string use brackets: `?ids[]=1&ids[]=2`. Where an endpoint takes `ids`, a comma-separated string works too. ## Responses Every response is a JSON object with `success`: ```json { "success": true, "data": [{"id": 42, "first_name": "Ada"}], "meta": {"total": 1, "page": 1, "per_page": 25} } ``` | Key | | |---|---| | `success` | `true` or `false` | | `data` | The resource, or a list of them | | `meta` | On lists: `total`, and usually `page` and `per_page` | | `message` | On writes: what happened, ready to show — "Tag created" | A write answers with the saved resource in `data` and a `message`. A delete answers `200` with only a `message`. ### Errors ```json {"success": false, "message": "A contact needs an email address."} ``` | Status | When | |---|---| | `401` | Not signed in | | `403` | Signed in without CRM access, or without the capability for this action | | `404` | No such record, or a module that is switched off | | `409` | An automation was saved by someone else since you loaded it | | `422` | The input is not valid. `message` says why; some endpoints add `data.errors` | | `429` | A public endpoint was called too often | ## Lists List endpoints take the same parameters: | Parameter | Default | | |---|---|---| | `page` | `1` | | | `per_page` | `25` | At most `100` | | `search` | | Free text, where the list supports it | | `orderby` | `id` | Only the columns the list allows; anything else falls back to the default | | `order` | `desc` | `asc` or `desc` | `meta.total` is the number of matching rows across all pages. ## Endpoints Paths are relative to `/wp-json/markercrm/v2/`. `{id}` is a numeric id. ### Contacts | Method | Path | Does | Capability | |---|---|---|---| | `GET` | `contacts` | List contacts. Filters: `search`, `status`, `channel`, `contact_type[]`, `tags[]`, `lists[]`, `segment`, `conditions`, `owner_id`, `company_id[]`, `not_company_id[]` | `view_contacts` | | `POST` | `contacts` | Create a contact, or update the one with the same address | `edit_contacts` | | `GET` | `contacts/counts` | Counts by status | `view_contacts` | | `POST` | `contacts/bulk` | Apply a bulk action to many contacts | `edit_contacts` | | `POST` | `contacts/bulk-delete` | Delete many contacts | `delete_contacts` | | `GET` | `contacts/{id}` | One contact | `view_contacts` | | `PUT` | `contacts/{id}` | Update a contact | `edit_contacts` | | `DELETE` | `contacts/{id}` | Delete a contact and everything it owns | `delete_contacts` | | `GET` | `contacts/{id}/sends` | Emails sent to the contact | `view_campaigns` | | `GET` | `contacts/{id}/links` | Links the contact clicked | `view_contacts` | | `GET` | `contacts/{id}/automations` | The contact's automation runs | `view_contacts`, `view_automations` | | `POST` | `contacts/{id}/automations` | Put the contact into an automation | `view_contacts`, `edit_automations` | | `GET` · `POST` | `contacts/{id}/direct-email` | Check whether a one-off email can be sent; send one | `view_contacts`, `send_campaigns` | | `POST` · `PUT` · `DELETE` | `contacts/{id}/companies` | Link a company, set the primary one, unlink | `edit_contacts` | The body of `POST contacts` and `PUT contacts/{id}` is what `ContactService::createOrUpdate()` takes: contact fields, `subscriptions`, `tags`, `lists`, `custom` and `company_id`. ### Tags and lists | Method | Path | Does | Capability | |---|---|---|---| | `GET` | `terms` | List terms of one `type` (`tag`, `list`, or an add-on type). Filters: `search`, `include[]` | `view_segments` or `view_contacts` | | `POST` | `terms` | Create a term | `edit_segments` | | `PUT` | `terms/{id}` | Update a term | `edit_segments` | | `DELETE` | `terms/{id}` | Delete a term and remove it from everyone | `delete_segments` | | `POST` | `terms/bulk-delete` | Delete many terms | `delete_segments` | | `POST` | `terms/{id}/visibility` | Make a list public or private | `edit_segments` | | `POST` | `terms/{id}/optin` | Set a list's own double opt-in | `edit_segments` | ### Segments | Method | Path | Does | Capability | |---|---|---|---| | `GET` | `segments` | List segments | `view_segments` | | `POST` | `segments` | Create a segment | `edit_segments` | | `GET` · `PUT` · `DELETE` | `segments/{id}` | Read, update, delete | `view_` · `edit_` · `delete_segments` | | `GET` | `segments/fields` | Every rule field, for building conditions | `view_segments` or `edit_automations` | | `POST` | `segments/preview` | Count and sample the contacts a `conditions` tree matches | `view_segments` | | `GET` | `segments/counts` | Contact counts for up to 100 segment `ids` | `view_segments` | ### Custom fields | Method | Path | Does | Capability | |---|---|---|---| | `GET` | `custom-fields` | List custom fields | `view_fields` or `view_contacts` | | `GET` | `custom-fields/types` | The field types | `view_fields` | | `POST` | `custom-fields` | Create a field | `edit_fields` | | `POST` | `custom-fields/reorder` | Change the order | `edit_fields` | | `PUT` · `DELETE` | `custom-fields/{key}` | Update, delete (by key) | `edit_fields` · `delete_fields` | ### Companies Only while the companies module is on. | Method | Path | Does | Capability | |---|---|---|---| | `GET` | `companies` | List companies | `view_companies` | | `GET` | `companies/counts` | Counts | `view_companies` | | `POST` | `companies` | Create a company | `edit_companies` | | `POST` | `companies/bulk` | Bulk action | `edit_companies`, or `delete_companies` to delete | | `GET` · `PUT` · `DELETE` | `companies/{id}` | Read, update, delete | `view_` · `edit_` · `delete_companies` | | `GET` | `companies/{id}/contacts` | The company's contacts | `view_contacts` | ### Imports and exports Pass `type=contacts` or `type=companies`. | Method | Path | Does | Capability | |---|---|---|---| | `GET` | `imports/sources` · `imports/fields` · `imports/sample` | Sources, mappable fields, a sample CSV in `data.csv` | `import_{type}` | | `POST` | `imports` | Upload a CSV and open an import | `import_{type}` | | `GET` · `PUT` · `DELETE` | `imports/{id}` | Read, save mapping and options, discard | `import_{type}` | | `GET` | `imports/{id}/preview` | The first rows, as mapped | `import_{type}` | | `POST` | `imports/{id}/start` · `imports/{id}/cancel` | Start, cancel | `import_{type}` | | `GET` | `imports/{id}/errors` | The rows that failed, as CSV text in `data.csv` | `import_{type}` | | `GET` | `exports/columns` | The columns an export can include | `export_{type}` | | `POST` | `exports/count` | How many records an export would hold | `export_{type}` | | `POST` | `exports` | Start an export | `export_{type}` | | `GET` · `DELETE` | `exports/{id}` | Read, delete | `export_{type}` | | `GET` | `exports/{id}/download` | Download the file | `export_{type}` | | `POST` | `exports/{id}/cancel` | Cancel | `export_{type}` | ### Automations | Method | Path | Does | Capability | |---|---|---|---| | `GET` | `automations` | List automations | `view_automations` | | `GET` | `automations/counts` | Counts by status | `view_automations` | | `POST` | `automations` | Create an automation | `edit_automations` | | `POST` | `automations/bulk` | Activate, pause or delete many | `edit_automations`, or `delete_automations` to delete | | `GET` | `automations/options/{source}` | Search an [option source](/developers/automations/fields/#option-sources) | `edit_automations` | | `GET` | `automations/recipes` | Ready-made automations | `edit_automations` | | `POST` | `automations/recipes/{key}` | Create one from a recipe | `edit_automations` | | `GET` · `PUT` · `DELETE` | `automations/{id}` | Read, save, delete | `view_` · `edit_` · `delete_automations` | | `POST` | `automations/{id}/status` | Turn on, pause, or set to draft | `edit_automations` | | `PUT` · `DELETE` | `automations/{id}/draft` | Save or discard a live automation's draft | `edit_automations` | | `POST` | `automations/{id}/publish` | Publish the draft | `edit_automations` | | `POST` | `automations/{id}/duplicate` | Copy it | `edit_automations` | | `POST` | `automations/{id}/test-email` · `automations/{id}/test-webhook` | Send a step as a test | `edit_automations` | | `GET` | `automations/{id}/report` | Report numbers | `view_automations` | | `GET` | `automations/{id}/sends` | Who got one of its emails (`step`) | `view_automations`, `view_contacts` | | `GET` | `automations/{id}/subscribers` | Its runs | `view_automations`, `view_contacts` | | `POST` | `automations/{id}/subscribers` | Add contacts by id, or by `audience` | `edit_automations`, `view_contacts` | | `POST` | `automations/{id}/subscribers/preview` | Count who an `audience` would add | `edit_automations`, `view_contacts` | | `GET` | `automations/{id}/subscribers/{run}` | One run's history | `view_automations`, `view_contacts` | | `POST` | `automations/{id}/subscribers/cancel` | Take active runs out | `edit_automations` | | `POST` | `automations/{id}/subscribers/remove` | Delete finished runs and their history | `delete_automations` | ### Campaigns | Method | Path | Does | Capability | |---|---|---|---| | `GET` | `campaigns` | List campaigns | `view_campaigns` | | `GET` | `campaigns/counts` | Counts by status | `view_campaigns` | | `GET` | `campaigns/audience-counts` | How many an audience would reach | `edit_campaigns` | | `POST` | `campaigns` | Create a campaign | `edit_campaigns` | | `POST` | `campaigns/bulk-delete` | Delete many | `delete_campaigns` | | `GET` · `PUT` · `DELETE` | `campaigns/{id}` | Read, save, delete | `view_` · `edit_` · `delete_campaigns` | | `POST` | `campaigns/{id}/duplicate` | Copy it | `edit_campaigns` | | `GET` | `campaigns/{id}/recipients` · `campaigns/{id}/sends` | Who it reaches; what was sent | `view_campaigns` | | `GET` | `campaigns/{id}/report` · `campaigns/{id}/preview` | Report; rendered preview | `view_campaigns` | | `POST` | `campaigns/{id}/test` | Send a test email | `edit_campaigns` | | `POST` | `campaigns/{id}/send` | Send now or schedule | `send_campaigns` | | `POST` | `campaigns/{id}/unschedule` · `pause` · `resume` · `cancel` | Change a send in progress | `send_campaigns` | | `POST` | `campaigns/{id}/resend` | Send again to a group of recipients | `send_campaigns` | | `POST` | `campaigns/{id}/ab/send-winner` | Send an A/B test's winner | `send_campaigns` | | `POST` · `DELETE` | `campaigns/{id}/repeat` | Make it recurring; stop repeating | `send_campaigns` | | `POST` | `campaigns/{id}/tag` | Tag or list a group of recipients | `view_campaigns`, `edit_contacts` | ### Emails, templates and patterns These need `edit_campaigns` or `edit_automations`, except where noted. | Method | Path | Does | |---|---|---| | `POST` | `emails/render` | Render an email body to HTML | | `POST` | `emails/footer` | Render the footer | | `GET` | `emails/action-links` | The action links an email can use | | `GET` · `POST` | `templates` | List, create | | `POST` | `templates/bulk` | Bulk action | | `GET` | `templates/{key}` · `templates/{key}/preview` | Read, preview | | `POST` | `templates/{key}/duplicate` | Copy | | `PUT` · `DELETE` | `templates/{id}` | Save, delete | | `GET` · `POST` | `email-patterns` | List, create | | `GET` | `email-patterns/library` | The built-in patterns | | `POST` | `email-patterns/bulk` | Bulk action | | `GET` · `PUT` · `DELETE` | `email-patterns/{id}` | Read, save, delete | ### Send log | Method | Path | Does | Capability | |---|---|---|---| | `GET` | `sends` | Every email sent, from any source | `view_logs` | | `DELETE` | `sends` | Delete log entries | `delete_logs`, or delete on what sent them | | `POST` | `sends/resend` · `sends/{id}/resend` | Send again | `send_campaigns` or `edit_automations`, by what sent them | | `GET` | `sends/{id}/preview` | The email as sent | `view_logs`, or view on what sent it | ### Notes | Method | Path | Does | Capability | |---|---|---|---| | `GET` | `notes` | Notes on a record: `object_type` and `object_id` | `view_` on that record type | | `POST` | `notes` | Log a note, call or meeting | `edit_` on that record type | | `PUT` · `DELETE` | `notes/{id}` | Update, delete | `edit_` · `delete_` on that record type | ### Reports | Method | Path | Does | Capability | |---|---|---|---| | `GET` | `reports/contacts` · `reports/email` | Contact and email reports | `view_reports` | | `GET` | `reports/dashboard` | The dashboard | `manage_dashboard` | ### Settings and administration All need `manage_settings`, except `users`. | Method | Path | Does | |---|---|---| | `GET` · `POST` | `settings/{group}` | Read, save a settings group | | `POST` | `settings/email/test` | Send a test email | | `GET` | `settings/email/bounces` | Bounce handling details | | `GET` · `POST` | `action-links` | List, create action links | | `PUT` · `DELETE` | `action-links/{id}` | Update, delete | | `GET` · `POST` | `webhooks` | List, create incoming webhooks | | `GET` | `webhooks/options` | What a webhook can do | | `GET` · `PUT` · `DELETE` | `webhooks/{id}` | Read, update, delete | | `POST` | `webhooks/{id}/reissue` | Issue a new URL token | | `GET` | `modules` | List modules | | `POST` | `modules/{slug}` | Switch a module on or off | | `GET` · `POST` | `permissions` | List, grant CRM permissions to a user | | `GET` | `permissions/capabilities` · `permissions/candidates` | The capability catalogue; users who can be granted | | `PUT` · `DELETE` | `permissions/{id}` | Update, revoke | | `GET` | `queue` | Queue status | | `POST` | `queue/retry` · `queue/run` | Retry failed jobs; run the queue now | | `GET` | `tools/report` | System report | | `POST` | `tools/repair` | Repair the database indexes | | `GET` · `DELETE` | `tools/logs` | Read, clear the system log | | `GET` | `users` | WordPress users a record can be assigned to — needs `view_contacts` | ### Public endpoints These need no sign-in. They are addressed by long random tokens, never by ids, rate limited, and answer an unknown token the same way as a disabled one. | Method | Path | Does | |---|---|---| | `POST` | `public/hooks/{token}` | An incoming webhook. The body is a JSON object; what it does is set on the webhook (**Settings → Webhooks**). Too many calls a minute answer `429` | | `GET` · `POST` | `public/bounces/{provider}/{key}` | A mail provider reporting bounces and complaints | Tracking pixels, click redirects, unsubscribe, preferences and opt-in confirmation are not REST routes: they are front-end URLs (`?marker_crm=…`), so they work without pretty permalinks.The Marker CRM admin is a single-page app that talks to its own REST API. You can use the same API from your add-on’s admin screens, or from outside WordPress.
Base URL: /wp-json/markercrm/v2/ — or rest_url('markercrm/v2/…') in PHP.
Authentication
Section titled “Authentication”Every endpoint except the few under public/ needs a signed-in WordPress user who has access
to the CRM. Marker CRM has no API keys of its own; it accepts whatever WordPress authenticates
for its REST API.
From the WordPress admin (your add-on’s own screen), send the logged-in cookie with a
wp_rest nonce:
// Enqueue your script with 'wp-api-fetch' as a dependency; it sends the nonce for you.const response = await wp.apiFetch({path: '/markercrm/v2/contacts?per_page=10'});With plain fetch, send a nonce made by wp_create_nonce('wp_rest') in the X-WP-Nonce
header, with credentials: 'same-origin'.
From outside WordPress, use an application password for a user with CRM access, over HTTPS:
curl -u "jane:abcd efgh ijkl mnop qrst uvwx" https://example.com/wp-json/markercrm/v2/contactsWho may do what
Section titled “Who may do what”A user has access to the CRM when they are an administrator (manage_options) or have been
given at least one Marker CRM permission on Settings → Permissions. Inside, each endpoint
checks a capability named marker_crm_{action}_{resource}:
| Resource | Actions |
|---|---|
contacts |
view edit delete import export |
companies |
view edit delete import export (companies module on) |
segments (tags, lists and segments) |
view edit delete |
fields (custom fields) |
view edit delete |
campaigns (campaigns and templates) |
view edit delete send |
automations |
view edit delete |
logs |
view delete |
reports |
view |
dashboard |
manage |
settings |
manage |
edit implies view; delete, import and send imply edit; export implies view.
Administrators hold every capability. Add-ons can add resources through
marker_crm/capabilities.
Requests
Section titled “Requests”- Send JSON bodies with
Content-Type: application/json. PUTandDELETEalso work as aPOSTwith anX-HTTP-Method-Overrideheader, which is what the admin does.- Arrays in a query string use brackets:
?ids[]=1&ids[]=2. Where an endpoint takesids, a comma-separated string works too.
Responses
Section titled “Responses”Every response is a JSON object with success:
{ "success": true, "data": [{"id": 42, "first_name": "Ada"}], "meta": {"total": 1, "page": 1, "per_page": 25}}| Key | |
|---|---|
success |
true or false |
data |
The resource, or a list of them |
meta |
On lists: total, and usually page and per_page |
message |
On writes: what happened, ready to show — “Tag created” |
A write answers with the saved resource in data and a message. A delete answers 200 with
only a message.
Errors
Section titled “Errors”{"success": false, "message": "A contact needs an email address."}| Status | When |
|---|---|
401 |
Not signed in |
403 |
Signed in without CRM access, or without the capability for this action |
404 |
No such record, or a module that is switched off |
409 |
An automation was saved by someone else since you loaded it |
422 |
The input is not valid. message says why; some endpoints add data.errors |
429 |
A public endpoint was called too often |
List endpoints take the same parameters:
| Parameter | Default | |
|---|---|---|
page |
1 |
|
per_page |
25 |
At most 100 |
search |
Free text, where the list supports it | |
orderby |
id |
Only the columns the list allows; anything else falls back to the default |
order |
desc |
asc or desc |
meta.total is the number of matching rows across all pages.
Endpoints
Section titled “Endpoints”Paths are relative to /wp-json/markercrm/v2/. {id} is a numeric id.
Contacts
Section titled “Contacts”| Method | Path | Does | Capability |
|---|---|---|---|
GET |
contacts |
List contacts. Filters: search, status, channel, contact_type[], tags[], lists[], segment, conditions, owner_id, company_id[], not_company_id[] |
view_contacts |
POST |
contacts |
Create a contact, or update the one with the same address | edit_contacts |
GET |
contacts/counts |
Counts by status | view_contacts |
POST |
contacts/bulk |
Apply a bulk action to many contacts | edit_contacts |
POST |
contacts/bulk-delete |
Delete many contacts | delete_contacts |
GET |
contacts/{id} |
One contact | view_contacts |
PUT |
contacts/{id} |
Update a contact | edit_contacts |
DELETE |
contacts/{id} |
Delete a contact and everything it owns | delete_contacts |
GET |
contacts/{id}/sends |
Emails sent to the contact | view_campaigns |
GET |
contacts/{id}/links |
Links the contact clicked | view_contacts |
GET |
contacts/{id}/automations |
The contact’s automation runs | view_contacts, view_automations |
POST |
contacts/{id}/automations |
Put the contact into an automation | view_contacts, edit_automations |
GET · POST |
contacts/{id}/direct-email |
Check whether a one-off email can be sent; send one | view_contacts, send_campaigns |
POST · PUT · DELETE |
contacts/{id}/companies |
Link a company, set the primary one, unlink | edit_contacts |
The body of POST contacts and PUT contacts/{id} is what
ContactService::createOrUpdate() takes: contact fields, subscriptions, tags, lists,
custom and company_id.
Tags and lists
Section titled “Tags and lists”| Method | Path | Does | Capability |
|---|---|---|---|
GET |
terms |
List terms of one type (tag, list, or an add-on type). Filters: search, include[] |
view_segments or view_contacts |
POST |
terms |
Create a term | edit_segments |
PUT |
terms/{id} |
Update a term | edit_segments |
DELETE |
terms/{id} |
Delete a term and remove it from everyone | delete_segments |
POST |
terms/bulk-delete |
Delete many terms | delete_segments |
POST |
terms/{id}/visibility |
Make a list public or private | edit_segments |
POST |
terms/{id}/optin |
Set a list’s own double opt-in | edit_segments |
Segments
Section titled “Segments”| Method | Path | Does | Capability |
|---|---|---|---|
GET |
segments |
List segments | view_segments |
POST |
segments |
Create a segment | edit_segments |
GET · PUT · DELETE |
segments/{id} |
Read, update, delete | view_ · edit_ · delete_segments |
GET |
segments/fields |
Every rule field, for building conditions | view_segments or edit_automations |
POST |
segments/preview |
Count and sample the contacts a conditions tree matches |
view_segments |
GET |
segments/counts |
Contact counts for up to 100 segment ids |
view_segments |
Custom fields
Section titled “Custom fields”| Method | Path | Does | Capability |
|---|---|---|---|
GET |
custom-fields |
List custom fields | view_fields or view_contacts |
GET |
custom-fields/types |
The field types | view_fields |
POST |
custom-fields |
Create a field | edit_fields |
POST |
custom-fields/reorder |
Change the order | edit_fields |
PUT · DELETE |
custom-fields/{key} |
Update, delete (by key) | edit_fields · delete_fields |
Companies
Section titled “Companies”Only while the companies module is on.
| Method | Path | Does | Capability |
|---|---|---|---|
GET |
companies |
List companies | view_companies |
GET |
companies/counts |
Counts | view_companies |
POST |
companies |
Create a company | edit_companies |
POST |
companies/bulk |
Bulk action | edit_companies, or delete_companies to delete |
GET · PUT · DELETE |
companies/{id} |
Read, update, delete | view_ · edit_ · delete_companies |
GET |
companies/{id}/contacts |
The company’s contacts | view_contacts |
Imports and exports
Section titled “Imports and exports”Pass type=contacts or type=companies.
| Method | Path | Does | Capability |
|---|---|---|---|
GET |
imports/sources · imports/fields · imports/sample |
Sources, mappable fields, a sample CSV in data.csv |
import_{type} |
POST |
imports |
Upload a CSV and open an import | import_{type} |
GET · PUT · DELETE |
imports/{id} |
Read, save mapping and options, discard | import_{type} |
GET |
imports/{id}/preview |
The first rows, as mapped | import_{type} |
POST |
imports/{id}/start · imports/{id}/cancel |
Start, cancel | import_{type} |
GET |
imports/{id}/errors |
The rows that failed, as CSV text in data.csv |
import_{type} |
GET |
exports/columns |
The columns an export can include | export_{type} |
POST |
exports/count |
How many records an export would hold | export_{type} |
POST |
exports |
Start an export | export_{type} |
GET · DELETE |
exports/{id} |
Read, delete | export_{type} |
GET |
exports/{id}/download |
Download the file | export_{type} |
POST |
exports/{id}/cancel |
Cancel | export_{type} |
Automations
Section titled “Automations”| Method | Path | Does | Capability |
|---|---|---|---|
GET |
automations |
List automations | view_automations |
GET |
automations/counts |
Counts by status | view_automations |
POST |
automations |
Create an automation | edit_automations |
POST |
automations/bulk |
Activate, pause or delete many | edit_automations, or delete_automations to delete |
GET |
automations/options/{source} |
Search an option source | edit_automations |
GET |
automations/recipes |
Ready-made automations | edit_automations |
POST |
automations/recipes/{key} |
Create one from a recipe | edit_automations |
GET · PUT · DELETE |
automations/{id} |
Read, save, delete | view_ · edit_ · delete_automations |
POST |
automations/{id}/status |
Turn on, pause, or set to draft | edit_automations |
PUT · DELETE |
automations/{id}/draft |
Save or discard a live automation’s draft | edit_automations |
POST |
automations/{id}/publish |
Publish the draft | edit_automations |
POST |
automations/{id}/duplicate |
Copy it | edit_automations |
POST |
automations/{id}/test-email · automations/{id}/test-webhook |
Send a step as a test | edit_automations |
GET |
automations/{id}/report |
Report numbers | view_automations |
GET |
automations/{id}/sends |
Who got one of its emails (step) |
view_automations, view_contacts |
GET |
automations/{id}/subscribers |
Its runs | view_automations, view_contacts |
POST |
automations/{id}/subscribers |
Add contacts by id, or by audience |
edit_automations, view_contacts |
POST |
automations/{id}/subscribers/preview |
Count who an audience would add |
edit_automations, view_contacts |
GET |
automations/{id}/subscribers/{run} |
One run’s history | view_automations, view_contacts |
POST |
automations/{id}/subscribers/cancel |
Take active runs out | edit_automations |
POST |
automations/{id}/subscribers/remove |
Delete finished runs and their history | delete_automations |
Campaigns
Section titled “Campaigns”| Method | Path | Does | Capability |
|---|---|---|---|
GET |
campaigns |
List campaigns | view_campaigns |
GET |
campaigns/counts |
Counts by status | view_campaigns |
GET |
campaigns/audience-counts |
How many an audience would reach | edit_campaigns |
POST |
campaigns |
Create a campaign | edit_campaigns |
POST |
campaigns/bulk-delete |
Delete many | delete_campaigns |
GET · PUT · DELETE |
campaigns/{id} |
Read, save, delete | view_ · edit_ · delete_campaigns |
POST |
campaigns/{id}/duplicate |
Copy it | edit_campaigns |
GET |
campaigns/{id}/recipients · campaigns/{id}/sends |
Who it reaches; what was sent | view_campaigns |
GET |
campaigns/{id}/report · campaigns/{id}/preview |
Report; rendered preview | view_campaigns |
POST |
campaigns/{id}/test |
Send a test email | edit_campaigns |
POST |
campaigns/{id}/send |
Send now or schedule | send_campaigns |
POST |
campaigns/{id}/unschedule · pause · resume · cancel |
Change a send in progress | send_campaigns |
POST |
campaigns/{id}/resend |
Send again to a group of recipients | send_campaigns |
POST |
campaigns/{id}/ab/send-winner |
Send an A/B test’s winner | send_campaigns |
POST · DELETE |
campaigns/{id}/repeat |
Make it recurring; stop repeating | send_campaigns |
POST |
campaigns/{id}/tag |
Tag or list a group of recipients | view_campaigns, edit_contacts |
Emails, templates and patterns
Section titled “Emails, templates and patterns”These need edit_campaigns or edit_automations, except where noted.
| Method | Path | Does |
|---|---|---|
POST |
emails/render |
Render an email body to HTML |
POST |
emails/footer |
Render the footer |
GET |
emails/action-links |
The action links an email can use |
GET · POST |
templates |
List, create |
POST |
templates/bulk |
Bulk action |
GET |
templates/{key} · templates/{key}/preview |
Read, preview |
POST |
templates/{key}/duplicate |
Copy |
PUT · DELETE |
templates/{id} |
Save, delete |
GET · POST |
email-patterns |
List, create |
GET |
email-patterns/library |
The built-in patterns |
POST |
email-patterns/bulk |
Bulk action |
GET · PUT · DELETE |
email-patterns/{id} |
Read, save, delete |
Send log
Section titled “Send log”| Method | Path | Does | Capability |
|---|---|---|---|
GET |
sends |
Every email sent, from any source | view_logs |
DELETE |
sends |
Delete log entries | delete_logs, or delete on what sent them |
POST |
sends/resend · sends/{id}/resend |
Send again | send_campaigns or edit_automations, by what sent them |
GET |
sends/{id}/preview |
The email as sent | view_logs, or view on what sent it |
| Method | Path | Does | Capability |
|---|---|---|---|
GET |
notes |
Notes on a record: object_type and object_id |
view_ on that record type |
POST |
notes |
Log a note, call or meeting | edit_ on that record type |
PUT · DELETE |
notes/{id} |
Update, delete | edit_ · delete_ on that record type |
Reports
Section titled “Reports”| Method | Path | Does | Capability |
|---|---|---|---|
GET |
reports/contacts · reports/email |
Contact and email reports | view_reports |
GET |
reports/dashboard |
The dashboard | manage_dashboard |
Settings and administration
Section titled “Settings and administration”All need manage_settings, except users.
| Method | Path | Does |
|---|---|---|
GET · POST |
settings/{group} |
Read, save a settings group |
POST |
settings/email/test |
Send a test email |
GET |
settings/email/bounces |
Bounce handling details |
GET · POST |
action-links |
List, create action links |
PUT · DELETE |
action-links/{id} |
Update, delete |
GET · POST |
webhooks |
List, create incoming webhooks |
GET |
webhooks/options |
What a webhook can do |
GET · PUT · DELETE |
webhooks/{id} |
Read, update, delete |
POST |
webhooks/{id}/reissue |
Issue a new URL token |
GET |
modules |
List modules |
POST |
modules/{slug} |
Switch a module on or off |
GET · POST |
permissions |
List, grant CRM permissions to a user |
GET |
permissions/capabilities · permissions/candidates |
The capability catalogue; users who can be granted |
PUT · DELETE |
permissions/{id} |
Update, revoke |
GET |
queue |
Queue status |
POST |
queue/retry · queue/run |
Retry failed jobs; run the queue now |
GET |
tools/report |
System report |
POST |
tools/repair |
Repair the database indexes |
GET · DELETE |
tools/logs |
Read, clear the system log |
GET |
users |
WordPress users a record can be assigned to — needs view_contacts |
Public endpoints
Section titled “Public endpoints”These need no sign-in. They are addressed by long random tokens, never by ids, rate limited, and answer an unknown token the same way as a disabled one.
| Method | Path | Does |
|---|---|---|
POST |
public/hooks/{token} |
An incoming webhook. The body is a JSON object; what it does is set on the webhook (Settings → Webhooks). Too many calls a minute answer 429 |
GET · POST |
public/bounces/{provider}/{key} |
A mail provider reporting bounces and complaints |
Tracking pixels, click redirects, unsubscribe, preferences and opt-in confirmation are not REST
routes: they are front-end URLs (?marker_crm=…), so they work without pretty permalinks.