Jetpack CRM API 文档
Jetpack CRM API 文档,介绍 CRM 接口用法。
Introduction
Welcome to the Jetpack CRM API v2.0. The API can be used to talk to Jetpack CRM from another application.
All endpoints live under your CRM site's API root:
https://{your-site}/zbs_api/{endpoint}
Requirements
- Jetpack CRM v6.0+
- WordPress v6.0+
- PHP 7.4+
- Pretty permalinks enabled in Settings → Permalinks. Default permalinks will not work because the API uses custom rewrite endpoints.
Errors
The Jetpack CRM API returns the following error codes:
| Error Code | Meaning |
|---|---|
| 400 | Bad Request. Your request is invalid or the endpoint is unknown. |
| 401 | Unauthorized. Your API key or secret is wrong. |
| 403 | Forbidden. You do not have permission to access this resource. |
| 405 | Method Not Allowed. You used an HTTP method the endpoint doesn't accept. |
| 418 | I'm a teapot. You tried the BREW method. |
Parameters
Every request must include your API credentials as query parameters (see Authentication).
Pagination
List endpoints accept:
page: page number, starting at1(default:1)perpage: results per page (default:10)order: sort direction,ASCorDESC(default:DESC)
Ownership / Assignment
Jetpack CRM has an ownership and assignment model: results can be restricted to records owned by, or assigned to, a specific CRM team member. Endpoints that support this accept the assign, owned, or owner parameters (see each endpoint for details).
Other
zbs_query: search phrase for endpoints that support filteringreplace_hyphens_with_underscores_in_json_keys: set to1to rewrite hyphens to underscores in JSON keys (useful for integrations like Zapier that reject hyphenated keys)external_api_name: string identifier for the calling integration, surfaced in logs/webhooks
Authentication
The API key and secret are passed as query parameters on every request:
/zbs_api/{endpoint}?api_key={your_api_key}&api_secret={your_api_secret}
Jetpack CRM uses an API key + secret pair to authenticate requests. Generate yours from the CRM admin (see How to Generate API Keys).
- Publishable key:
jpcrm_pk_... - Secret key:
jpcrm_sk_...
The credentials grant both read and write access to your CRM, so treat the secret like a password.
Status
Get Status
A lightweight health-check endpoint. Use it to verify your API credentials and check the running CRM version before making any other calls.
HTTP Request
GET /status
Optional query parameters:
full: if present (any value), the response also includes installed core modules and active pro extensions.
JSON response example:
{
"success": true,
"data": {
"status": "Successful Connection",
"message": "Your API Connection with Jetpack CRM is functioning correctly.",
"crm_version": "6.7.2",
"db_version": "4.3"
}
}
With
?full=1:
{
"success": true,
"data": {
"status": "Successful Connection",
"message": "Your API Connection with Jetpack CRM is functioning correctly.",
"crm_version": "6.7.2",
"db_version": "4.3",
"modules": {
"mail-campaigns": true,
"client-portal": true
},
"extensions": {
"stripe": { "name": "Stripe Sync", "version": "2.4.0" }
}
}
}
Customers
Create Customer
Creates or updates a customer. The unique key is the email address; if a matching contact exists it is updated, otherwise a new one is created. Pass id to update a specific contact regardless of email. On success the response echoes the data you sent plus the new id (if created).
HTTP Request
POST /create_customer
Send a JSON body. Common fields:
email(string): customer email. Unique key for create-or-update.id(int): existing contact ID. If set, updates that record.status(string): one ofLead,Customer,Refused. Other custom statuses are also accepted.prefix,fname,lname(string): name fields.addr1,addr2,city,county,postcode,country(string): main address.secaddr1,secaddr2,seccity,seccounty,secpostcode,seccountry(string): second address.hometel,worktel,mobtel(string): phone numbers.assign(int): WordPress user ID of the team member to own this contact.tags(array): list of tag strings to attach.{custom-field-slug}(mixed): any custom field by its slug.
<?php
$data = array(
'status' => 'Lead',
'prefix' => 'Mr',
'fname' => 'John',
'lname' => 'Doe',
'email' => 'someone@somewhere.com',
'hometel' => '1234 567 89',
'worktel' => '1234 567 89',
'mobtel' => '1234 567 89',
'addr1' => 'Sample House',
'addr2' => 'Sample Road',
'city' => 'Sample City',
'county' => 'Sample State',
'postcode' => 'P0ST C0D3',
'country' => 'UK',
'secaddr1' => 'Sample House 2',
'secaddr2' => 'Sample Road 2',
'seccity' => 'Sample City 2',
'seccounty' => 'Sample State 2',
'secpostcode' => 'P1ST C1D3',
'seccountry' => 'USA',
'tags' => array( 'newsletter', 'vip' ),
'assign' => 1,
'custom-field' => 'bacon',
);
?>
JSON response example:
{
"fname": "John",
"lname": "Doe",
"email": "johndoe@example.com",
"status": "Lead",
"prefix": "Mr",
"addr1": "1 Sample Road",
"city": "Sampleton",
"postcode": "SAM PL4",
"id": 135
}
View Customers
Returns a paginated list of customers. Each entry includes core fields plus any custom fields keyed by slug. Optionally include related invoices, quotes, transactions, and tags.
HTTP Request
POST /customers
Send a JSON body. All fields optional:
page(int): page number, default1.perpage(int): results per page, default10.search(string): filter by name/email substring.owned(int): WP user ID; only return contacts owned by this user.company(int): only return contacts attached to this company ID.tags(bool): include tags in each customer object. Default:false.invoices,quotes,transactions(bool): include related records in each customer object. Default:false.
<?php
$data = array(
'perpage' => 20,
'page' => 1,
'search' => 'doe',
'transactions' => true,
'invoices' => true,
'quotes' => true,
'tags' => true,
'owned' => 1,
'company' => 42,
);
?>
JSON response example:
[
{
"id": 20267,
"owner": 1,
"status": "Customer",
"email": "john@example.com",
"prefix": "Mr",
"fname": "John",
"lname": "Doe",
"addr1": "1 Sample Road",
"addr2": "",
"city": "Sampleton",
"county": "",
"country": "UK",
"postcode": "SAM PL4",
"hometel": "123 455",
"worktel": "",
"mobtel": "555 135",
"tw": "",
"li": "",
"fb": "",
"created": "2024-04-25 03:33:38",
"createduts": 1713994418,
"lastupdated": 1713994418,
"fullname": "John Doe",
"name": "John Doe",
"cf1": "Custom Field 1"
}
]
Search Customers
Search customers by free-text query against the deep meta (name, address, custom fields, etc.), or look up a single customer directly by email.
HTTP Request
GET /customer_search
Query parameters:
zbs_query(string): search phrase. Returns matching customers.email(string): exact email lookup. Returns one customer with related invoices, transactions, and tags attached.page,perpage,order: standard pagination.replace_hyphens_with_underscores_in_json_keys(int): set to1to rewrite hyphenated JSON keys to underscores (useful for Zapier, etc.).
<?php
// Free-text search:
// GET /zbs_api/customer_search?api_key=...&api_secret=...&zbs_query=doe
// Direct email lookup (includes financial data):
// GET /zbs_api/customer_search?api_key=...&api_secret=...&email=john@doe.com
?>
JSON response example (
zbs_querysearch returns an array):
[
{
"id": 20267,
"owner": 1,
"status": "Customer",
"email": "john@example.com",
"fname": "John",
"lname": "Doe",
"fullname": "John Doe",
"name": "John Doe",
"created": "2024-04-25 03:33:38"
}
]
JSON response example (
{
"id": 20267,
"owner": 1,
"status": "Customer",
"email": "john@example.com",
"fname": "John",
"lname": "Doe",
"fullname": "John Doe",
"created": "2024-04-25 03:33:38",
"invoices": [],
"transactions": [],
"tags": []
}
Companies
Create Company
Creates or updates a company. The unique key is the email address; if a matching company exists it is updated, otherwise a new one is created. Pass id to update a specific company regardless of email. On success the response echoes the data you sent plus the new id (if created).
HTTP Request
POST /create_company
Send a JSON body. Common fields:
name(string): company name.email(string): company email. Unique key for create-or-update.id(int): existing company ID. If set, updates that record.status(string): company status. If omitted, the CRM's default status is used.addr1,addr2,city,county,postcode,country(string): main address.secaddr1,secaddr2,seccity,seccounty,secpostcode,seccountry(string): second address.maintel,sectel(string): phone numbers.tw,li,fb(string): Twitter/LinkedIn/Facebook URLs.assign(int): WordPress user ID of the team member to own this company.tags(array): list of tag strings to attach.{custom-field-slug}(mixed): any custom field by its slug.
<?php
$data = array(
'name' => 'Acme Inc.',
'email' => 'hello@acme.com',
'status' => 'Customer',
'maintel' => '1234 567 89',
'sectel' => '1234 567 90',
'addr1' => 'Sample House',
'addr2' => 'Sample Road',
'city' => 'Sample City',
'county' => 'Sample State',
'postcode' => 'P0ST C0D3',
'country' => 'UK',
'secaddr1' => 'Sample House 2',
'secaddr2' => 'Sample Road 2',
'seccity' => 'Sample City 2',
'seccounty' => 'Sample State 2',
'secpostcode' => 'P1ST C1D3',
'seccountry' => 'USA',
'tags' => array( 'partner', 'priority' ),
'assign' => 1,
'custom-field' => 'bacon',
);
?>
JSON response example:
{
"name": "Acme Inc.",
"email": "hello@acme.com",
"status": "Customer",
"addr1": "Sample House",
"city": "Sample City",
"country": "UK",
"id": 442
}
View Companies
Returns a paginated list of companies.
HTTP Request
POST /companies
Send a JSON body. All fields optional:
page(int): page number, default1.perpage(int): results per page, default10.search(string): filter by name/email substring.owned(int): WP user ID; only return companies owned by this user.invoices,quotes,transactions(bool): include related records and totals for each company. Default:false.
<?php
$data = array(
'perpage' => 20,
'page' => 1,
'search' => 'acme',
'invoices' => true,
'transactions' => true,
'owned' => 1,
);
?>
JSON response example:
[
{
"id": 442,
"owner": 1,
"status": "Customer",
"name": "Acme Inc.",
"email": "hello@acme.com",
"addr1": "Sample House",
"addr2": "Sample Road",
"city": "Sample City",
"county": "Sample State",
"country": "UK",
"postcode": "P0ST C0D3",
"maintel": "1234 567 89",
"sectel": "",
"tw": "",
"li": "",
"fb": "",
"created": 1713994418,
"created_date": "2024-04-25",
"lastupdated": 1713994418,
"invoices_total": "1500.00",
"invoices_count": 3,
"transactions_total": "1500.00",
"transactions_paid_total": "1500.00",
"total_value": "1500.00"
}
]
Quotes
View Quotes
Returns a paginated list of quotes.
HTTP Request
GET /quotes
Query parameters: standard pagination (page, perpage, order).
JSON response example:
[
{
"id": 20069,
"owner": 1,
"id_override": "",
"title": "New Website",
"currency": "USD",
"value": "500.00",
"date": 1492185770,
"date_date": "2024-04-14",
"template": 3,
"content": "<p>Quote body HTML...</p>",
"notes": "",
"send_attachments": false,
"hash": "abcd1234",
"lastviewed": 0,
"lastviewed_date": false,
"viewed_count": 0,
"accepted": 0,
"accepted_date": false,
"created": 1492185770,
"created_date": "2024-04-14",
"lastupdated": 1492185770,
"lastupdated_date": "2024-04-14",
"status": -2
}
]
The status field is computed from other fields:
-1: draft (no template applied)-2: published, not yet accepted1: accepted
Invoices
View Invoices
Returns a paginated list of invoices.
HTTP Request
GET /invoices
Query parameters: standard pagination (page, perpage, order).
JSON response example:
[
{
"id": 20069,
"owner": 1,
"id_override": "INV-0042",
"parent": 0,
"status": "Unpaid",
"status_label": "Unpaid",
"hash": "abcd1234",
"currency": "USD",
"addressed_from": "Acme Inc.",
"addressed_to": "John Doe",
"address_to_objtype": 1,
"allow_partial": false,
"allow_tip": false,
"date": 1713994418,
"date_date": "2024-04-24",
"due_date": 1716586418,
"due_date_date": "2024-05-24",
"paid_date": 0,
"net": "500.00",
"discount": "0.00",
"discount_type": "percent",
"shipping": "0.00",
"tax": "0.00",
"total": "500.00",
"hash_viewed_count": 0,
"portal_viewed_count": 0,
"created": 1713994418,
"created_date": "2024-04-24 12:00:00",
"lastupdated": 1713994418
}
]
Transactions
Create Transaction
Creates or updates a transaction. If email matches an existing customer the transaction is attached to them; otherwise a new customer is created using the email and optional fname. Existing transactions with the same orderid are updated rather than duplicated.
HTTP Request
POST /create_transaction
Send a JSON body. Required:
orderid(string): unique reference. Stored asrefon the transaction.status(string): e.g.Completed,Refunded,Failed. Allowed values come from CRM settings (Transactions tab).total(string|number): grand total.
Optional:
email(string): customer email. Used to find or create the linked contact.fname(string): first name, used only when auto-creating a contact.date(int): Unix timestamp of the transaction. Auto-set if omitted.type(string): e.g.Sale,Refund.title,desc(string).currency(string): ISO code, e.g.USD.net,fee,discount,tax,shipping,shipping_tax(string|number).{custom-field-slug}(mixed): any custom field by its slug.
<?php
$data = array(
'orderid' => 'ORDER-0042',
'email' => 'john@example.com',
'fname' => 'John',
'status' => 'Completed',
'total' => '79.99',
'net' => '59.99',
'tax' => '0.00',
'fee' => '10.00',
'discount' => '10.00',
'currency' => 'USD',
'title' => 'Your Item Name',
);
?>
JSON response example (request body echoed back with new
id):
{
"orderid": "ORDER-0042",
"email": "john@example.com",
"fname": "John",
"status": "Completed",
"total": "79.99",
"net": "59.99",
"tax": "0.00",
"fee": "10.00",
"discount": "10.00",
"currency": "USD",
"title": "Your Item Name",
"id": 20286
}
View Transactions
Returns a paginated list of transactions.
HTTP Request
GET /transactions
Query parameters: standard pagination (page, perpage, order).
JSON response example:
[
{
"id": 20286,
"owner": 1,
"status": "Completed",
"type": "Sale",
"status_bool": 1,
"type_accounting": "credit",
"ref": "ORDER-0042",
"origin": "api",
"parent": 0,
"title": "My Awesome Order",
"desc": "",
"date": 1714237915,
"date_date": "2024-04-27 16:51:55",
"currency": "USD",
"net": "59.99",
"fee": "10.00",
"discount": "10.00",
"tax": "0.00",
"shipping": "0.00",
"total": "79.99",
"date_paid": 1714237915,
"date_paid_date": "2024-04-27 16:51:55",
"created": 1714237915,
"created_date": "2024-04-27 16:51:55",
"lastupdated": 1714237915
}
]
Notes:
status_boolis1if the status is configured to count as a successful transaction,-1otherwise. Configure which statuses count under Settings → Transactions in the CRM.type_accountingis a derived classification (credit/debit/ etc.) based on thetypevalue.
Events
Create Event
Creates or updates an event. Pass id to update an existing event.
HTTP Request
POST /create_event
Send a JSON body. All fields optional:
title(string): event title.customer(int): contact ID this event is attached to.notes(string): event description. Stored asdescon the record.from(string): start datetime, formatm/d/Y H:00:00.to(string): end datetime, same format.notify(int): set to24to schedule a reminder 24 hours beforefrom. Any other value disables notifications.complete(int):1to mark complete,0for incomplete.owner(int): WordPress user ID owning the event.-1for no owner.id(int): existing event ID to update.
<?php
$data = array(
'title' => 'Follow-up call',
'customer' => 44149,
'notes' => 'Discuss renewal options',
'from' => '02/01/2024 14:00:00',
'to' => '02/01/2024 15:00:00',
'notify' => 24,
'complete' => 0,
'owner' => 1,
);
?>
JSON response example (request body echoed back with new
id):
{
"title": "Follow-up call",
"customer": 44149,
"notes": "Discuss renewal options",
"to": "02/01/2024 15:00:00",
"from": "02/01/2024 14:00:00",
"notify": 24,
"complete": 0,
"owner": 1,
"id": 44155
}
View Events
Returns a paginated list of events.
HTTP Request
GET /events
Query parameters: standard pagination (page, perpage, order), plus:
owner(int): filter to events owned by this WordPress user ID.
JSON response example:
[
{
"id": 44155,
"owner": 1,
"title": "Follow-up call",
"desc": "Discuss renewal options",
"start": 1706799600,
"start_date": "2024-02-01 14:00:00",
"end": 1706803200,
"end_date": "2024-02-01 15:00:00",
"complete": 0,
"show_on_portal": 0,
"show_on_cal": 1,
"created": 1706796000,
"created_date": "2024-02-01 13:00:00",
"lastupdated": 1706796000
}
]
Notes:
- On read,
notesbecomesdesc, andfrom/tobecomestart/end(as Unix timestamps), plus formattedstart_date/end_date.
Errors
The Kittn API uses the following error codes:
| Error Code | Meaning |
|---|---|
| 400 | Bad Request -- Your request is invalid. |
| 401 | Unauthorized -- Your API key is wrong. |
| 403 | Forbidden -- The kitten requested is hidden for administrators only. |
| 404 | Not Found -- The specified kitten could not be found. |
| 405 | Method Not Allowed -- You tried to access a kitten with an invalid method. |
| 406 | Not Acceptable -- You requested a format that isn't json. |
| 410 | Gone -- The kitten requested has been removed from our servers. |
| 418 | I'm a teapot. |
| 429 | Too Many Requests -- You're requesting too many kittens! Slow down! |
| 500 | Internal Server Error -- We had a problem with our server. Try again later. |
| 503 | Service Unavailable -- We're temporarily offline for maintenance. Please try again later. |
SDK
Zero BS CRM has a GitHub repository for making connection to the API easy.