API & webhooks reference
A simple REST API to read and create your CRM records, plus signed webhooks for CRM events. All requests are scoped to the workspace that owns the API key.
Base URL
Every endpoint below is relative to:
https://mqcl-crm.com/api/v1Authentication
Generate a key in Settings → API & webhooks (workspace admins only). The full key is shown once at creation — store it securely. Send it as a Bearer token on every request:
curl https://mqcl-crm.com/api/v1/contacts \
-H "Authorization: Bearer mqcl_live_your_key_here"A missing or invalid key returns 401. Keys can be revoked anytime from the same settings page.
Endpoints
| Method | Path | Description |
|---|---|---|
| GET | /contacts | List contacts (supports ?search=) |
| GET | /contacts/:id | Retrieve one contact |
| POST | /contacts | Create a contact |
| GET | /companies | List companies (supports ?search=) |
| GET | /companies/:id | Retrieve one company |
| POST | /companies | Create a company |
| GET | /deals | List deals (supports ?search=) |
| GET | /deals/:id | Retrieve one deal |
| POST | /deals | Create a deal |
Creating records
Send JSON bodies. Successful creates return 201 with the new record under a data key.
Create a contact
curl -X POST https://mqcl-crm.com/api/v1/contacts \
-H "Authorization: Bearer mqcl_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"firstName": "Jane",
"lastName": "Doe",
"email": "jane@acme.com",
"status": "WARM"
}'Create a company
curl -X POST https://mqcl-crm.com/api/v1/companies \
-H "Authorization: Bearer mqcl_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{ "name": "Acme Inc", "domain": "acme.com", "website": "https://acme.com" }'Create a deal
stageId is optional — omit it and the deal lands in the first stage of your default pipeline.
curl -X POST https://mqcl-crm.com/api/v1/deals \
-H "Authorization: Bearer mqcl_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{ "name": "Acme expansion", "amount": 5000, "currency": "USD" }'Errors
Errors return a matching HTTP status and a JSON body:
{ "error": { "message": "Invalid or revoked API key." } }Validation failures return 422 with an issues array describing each field. Unknown records return 404.
Webhooks
Add an endpoint in Settings → API & webhooks and subscribe to the events you care about. When an event fires we POST a signed JSON payload to your URL.
| Event | Fires when |
|---|---|
| contact.created | A contact was created |
| deal.created | A deal was created |
| deal.stage_changed | A deal moved to a different stage |
| deal.won | A deal was marked won |
| deal.lost | A deal was marked lost |
Payload
POST https://your-endpoint.example.com
X-MQCL-Event: deal.won
X-MQCL-Signature: sha256=<hmac>
{
"event": "deal.won",
"workspaceId": "…",
"occurredAt": "2026-06-12T09:30:00.000Z",
"data": { "id": "…", "name": "Acme expansion", "amount": 5000 }
}Verify the signature
Each delivery is signed with your endpoint's secret (shown once when you add it). Recompute the HMAC over the raw request body and compare:
import crypto from 'node:crypto';
function isValid(rawBody, signatureHeader, secret) {
const expected =
'sha256=' + crypto.createHmac('sha256', secret).update(rawBody).digest('hex');
return crypto.timingSafeEqual(
Buffer.from(expected),
Buffer.from(signatureHeader),
);
}Respond with a 2xx status to acknowledge. Non-2xx responses and timeouts are recorded in the endpoint's recent-delivery log.
Ready to build? Generate a key in your workspace settings and start calling the API.