Skip to content

REST API

PrimoCRM registers its REST routes under the primocrm/v1 namespace on rest_api_init. The admin app uses these same endpoints, so anything the UI does is available programmatically.

https://yoursite.com/wp-json/primocrm/v1/

Every endpoint has a permission callback that checks a WordPress capability, so a caller must be authenticated and authorized.

  • From the admin app (same origin): requests are authenticated by the logged-in session and a REST nonce. WordPress sends the nonce in the X-WP-Nonce header. This is automatic for code running inside wp-admin.
  • From external code: use an authentication method WordPress accepts for the REST API, such as application passwords, together with a user who has the required capability. PrimoCRM Pro adds dedicated API keys for programmatic access.

Endpoints that manage settings, sending, or destructive operations require an administrator-level capability. Read and routine contact operations require the CRM access capability.

The list below is a representative sample, not exhaustive. Explore the full set from the browser network tab while using the admin app, since the UI calls the same routes.

Method Path Purpose
GET /contacts List contacts (supports paging and filters)
POST /contacts Create a contact
GET /contacts/{id} Get one contact
PUT /contacts/{id} Update a contact
DELETE /contacts/{id} Delete a contact
POST /contacts/bulk-action Apply a bulk action to many contacts
POST /contacts/bulk-delete Delete many contacts
GET /contacts/statuses List available statuses
GET /contacts/{id}/activities A contact’s activity log
GET /contacts/{id}/emails Emails sent to a contact
Method Path Purpose
GET /automations/triggers All registered triggers
GET /automations/actions All registered actions
GET /automations/condition-options Fields and operators for the condition builder
Method Path Purpose
GET /forms/field-types All registered form field types
GET /smart-codes The personalization tag catalog

Campaigns, sequences, lists, tags, templates, migration, and settings each expose their own routes under the same namespace, following the same controller pattern.

Creating a contact with application-password auth:

Terminal window
curl -X POST https://yoursite.com/wp-json/primocrm/v1/contacts \
-u "admin:APPLICATION_PASSWORD" \
-H "Content-Type: application/json" \
-d '{"email":"ada@example.com","first_name":"Ada","status":"subscribed"}'

Successful responses return JSON. Errors return a JSON body with a message you can show to a person, and an HTTP status that says what went wrong: 400 for input the endpoint refuses, 401 or 403 when the request is not authorized (not logged in, or missing the capability), 404 when the item does not exist.

PrimoCRM has no plan limits and no locked endpoints. A route another plugin adds, such as those of PrimoCRM Pro, exists only while that plugin is active; without it the route returns 404. Saving something that nothing on the site provides, for example an automation trigger whose plugin is not installed or a mail provider that is not registered, is refused with a 400 and a message saying so.