Developers

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/v1

Authentication

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

MethodPathDescription
GET/contactsList contacts (supports ?search=)
GET/contacts/:idRetrieve one contact
POST/contactsCreate a contact
GET/companiesList companies (supports ?search=)
GET/companies/:idRetrieve one company
POST/companiesCreate a company
GET/dealsList deals (supports ?search=)
GET/deals/:idRetrieve one deal
POST/dealsCreate 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.

EventFires when
contact.createdA contact was created
deal.createdA deal was created
deal.stage_changedA deal moved to a different stage
deal.wonA deal was marked won
deal.lostA 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.