Quantom API
A full read and write REST API for your CRM. Every request carries a bearer key, and every key is held to the permissions of the person who made it.
https://crm-api.curepay.devGetting started
That hostname serves the API and nothing else. It answers /api/...,
returns 404 for everything else, and has no sign-in page because there is no session to
have.
Create a key in Quantom under Integrations, then Developer REST API. It is shown once. Send it on every request:
curl https://crm-api.curepay.dev/api/deals \
-H 'Authorization: Bearer cpk_your_key'
Authentication, and what a key can do
An owner's key can do everything an owner can, including delete, from anywhere, with no second factor. Scope it when you make it: the form offers every permission you hold, and a key for a website form needs one of them, not all of them.
A key can also be given a lifetime. A key with no expiry never expires, which is the right choice for a sync you own and the wrong one for a contractor.
Keys cannot manage keys. A leaked key cannot mint itself a replacement, so revoking it in Quantom stops it immediately and permanently.
Errors, and how to read a 403
Errors are JSON with an error field. A 403 from a scoped key also names
the permission it wanted, so you can go and tick that one rather than guessing:
{ "error": "That API key doesn't grant this.", "perm": "deals.view" }
401 means the key is wrong, expired or missing. 403 means the
key is good and the permission is not. 404 means the path is not one this API
serves.
Endpoints
The permission beside each route is the one it checks. Two names joined by + means it wants both: a section gate, and a second check inside it.
The pipeline
/api/dealsRequiresdeals.view
Every deal, paged. ?limit= and ?cursor=. Each carries cpid, the CurePay id of the client it became, and did, its Deal ID (DID-2025-0012) once it is on that client's Deals tab; both are empty until then.
/api/deals/{id}Requiresdeals.view
One deal, whole, with its did and cpid. {id} is the deal's id or any Deal ID; a DID that is not a pipeline deal (a register deal, a Service Program, a marketing contract) answers with its Client IQ row.
/api/dealsRequiresdeals.edit
Create one. { name*, company, email, phone, value, stage, source, address }. A new deal has no did until it is on a client's Deals tab.
/api/contactsRequirescontacts.view
Contacts, paged.
/api/contactsRequirescontacts.edit
Create one. { name*, email, phone, company }
/api/tasksRequirescalendar.view
Open tasks.
/api/tasksRequirescalendar.edit
Create one. { title*, due, related }
Customer reports
/api/clienttasks/report?client=&period=monthRequiresclienttasks.view + reports.view
THE CUSTOMER REPORT. A month or a quarter of everything for one client, next to the period before it. client= is the name, the id or the CPID (CPID-2025-0007), or send cpid= instead. period=month|quarter. Takes both rights: the section gate and the money on the page.
/api/reports/runRequiresreports.view
Run any report the builder can build. { entity, groupBy, measures, dateField, from, to, filters }
/api/clienttasks/projection?client=Requiresclientiq.view + commerce.view
Seven years of projected revenue for one client.
/api/goalsRequiresreports.view
Goal attainment and the weighted pipeline forecast.
/api/clienttasks/deals?did=Requiresclientiq.view
One deal by its DID (DID-2025-0013), with the client it is on, whoever's it is. Leave did= off for every Client IQ deal in the book, 500 a page, with ?cursor= for the next. Only deals on a client's Deals tab: canvassing leads are not deals and are not here.
/api/clienttasks/deals?client=Requiresclientiq.view
Every deal on one client, one row each, as the Deals tab lists them: the register's processing deal and its Service Program are two deals, each marketing contract and one-off is one, and so is each pipeline deal on a line. Each has its did (DID-2025-0012). client= is the name or the CPID, or send cpid=.
/api/clienttasks/intel?client=Requiresclientiq.view
One client’s intelligence payload: onboarding, revenue, work, documents. client= is the name or the CPID; the CPID picks the exact client where two share a name.
/api/clienttasks/spine?mid=Requiresclientiq.view
One merchant from the deal that sold it to the last residual it earned.
Clients
/api/clienttasks?slim=1Requiresclienttasks.view
The client roster. slim=1 returns id, cpid, name, status, token and setup only.
/api/clienttasks/client?id=Requiresclienttasks.view
One client, whole. id= is the client id or its CPID.
/api/clienttasks/deliverableRequiresclienttasks.edit
File something made for a client onto their record. { clientId*, tool*, name, ref* }
Marketing
/api/campaignsRequiresmarketing.view
Campaigns and their attributed leads.
/api/contentRequiresmarketing.view
The Content Writer library.
/api/docsRequiresmarketing.view
Shared PDFs: name, size, who uploaded it, how many times it has been opened, and the public link.
/api/content/outlineRequiresmarketing.edit
Plan a piece. { brief }
/api/content/draftRequiresmarketing.edit
Write it from an outline. { brief, outline }
Commerce
/api/invoicing/invoicesRequirescommerce.view
Every saved invoice, with who and how much.
/api/invoicing/invoices/{number}Requirescommerce.view
One invoice, whole.
How to connect it
1Pull a customer report every month
The report behind a client's monthly review: this period against the one before it, with the figures the CRM recorded rather than estimated.
curl 'https://crm-api.curepay.dev/api/clienttasks/report?cpid=CPID-2025-0007&period=month' \
-H 'Authorization: Bearer cpk_your_key'
Takes two rights: clienttasks.view to reach the section and reports.view because it puts money on the page. period is month or quarter. Ask by CPID where you have it: a name is matched too, but two clients can share one, and the CPID is the exact client.
2Put a website enquiry straight into the pipeline
The usual first integration. Your contact form posts here and the deal appears on the board with a source you can report on.
curl -X POST https://crm-api.curepay.dev/api/deals \
-H 'Authorization: Bearer cpk_your_key' \
-H 'content-type: application/json' \
-d '{"name":"Jane Reyes","company":"Acme Dental","email":"jane@acme.com",
"phone":"555-0142","value":4800,"source":"Website form"}'
Scope this key to deals.edit and nothing else. A form key that can also read payroll is a form key that reads payroll the day the site is compromised.
3Sync the client roster into a spreadsheet
The slim roster is the whole client list with six fields on it, CPID included, which is what a sheet wants. The full record is one call per client and is rarely what you mean.
curl 'https://crm-api.curepay.dev/api/clienttasks?slim=1' \
-H 'Authorization: Bearer cpk_your_key'
Drop the ?slim=1 and every field comes back, which on 1,700 clients is about 1.5 MB. Ask for slim unless you need the rest.
4Wire it to Zapier, n8n or Make
All three speak plain HTTP, so there is no connector to install: a Webhooks step with a bearer header is the whole integration.
URL https://crm-api.curepay.dev/api/deals
Method POST
Headers Authorization: Bearer cpk_your_key
content-type: application/json
Body {"name":"{{name}}","email":"{{email}}","source":"Zapier"}
Give each tool its own key and name it after the tool. When something starts behaving oddly you revoke one key rather than guessing which of five things broke.
5Write a page for a client from your own script
The Content Writer plans first and drafts from the plan, so it is two calls. The outline comes back as JSON you can edit before you spend the second one.
curl -X POST https://crm-api.curepay.dev/api/content/outline \
-H 'Authorization: Bearer cpk_your_key' -H 'content-type: application/json' \
-d '{"brief":{"topic":"How much does a card terminal cost?","len":"standard"}}'
# then, with the sections it returned (edited or not):
curl -X POST https://crm-api.curepay.dev/api/content/draft \
-H 'Authorization: Bearer cpk_your_key' -H 'content-type: application/json' \
-d '{"brief":{...},"outline":[{"heading":"...","level":2,"words":300}]}'
Both cost a model call, so both take marketing.edit. A draft of two thousand words takes about thirty seconds and is not streamed.