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.
Base URL
Section titled “Base URL”https://yoursite.com/wp-json/primocrm/v1/Authentication
Section titled “Authentication”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-Nonceheader. 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.
Representative endpoints
Section titled “Representative endpoints”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.
Contacts
Section titled “Contacts”| 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 |
Automations
Section titled “Automations”| 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 |
Forms and smart codes
Section titled “Forms and smart codes”| 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.
Example request
Section titled “Example request”Creating a contact with application-password auth:
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"}'Response shape
Section titled “Response shape”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.