DispatchMind API for developers
The DispatchMind API lets a company connect its own systems and lead sources: accounting, reporting, an answering service, a lead marketplace, or a tool like Zapier. Read jobs, customers and payments; add jobs, leads and notes; and get a webhook the moment something changes. Partner apps connect with a Connect DispatchMind button instead of a key.
Get an API key
- An owner or admin opens the account menu (top right), then Sign-in and security, then Manage API keys and webhooks.
- Name the key (for example "Accounting sync"), pick what it can do, and tap Make an API key:
- Read only: jobs, customers and payments.
- Read and add: everything above, plus adding jobs, leads and notes.
- Lead address only: gives you a web address a lead source can send leads to. It can't read anything.
- Copy the key right away. It starts with
dm_live_and is shown only once. DispatchMind keeps only a fingerprint of it, never the key itself.
A key acts as the person who made it. It sees exactly what that login can see, and it stops working the moment that login is switched off or the key is revoked.
Make a request
Send the key in the Authorization header. Every address starts with https://app.dispatchmind.ai/v1.
curl https://app.dispatchmind.ai/v1/jobs?limit=20 \
-H "Authorization: Bearer dm_live_YOUR_KEY"
| Endpoint | What it returns |
|---|---|
GET /v1/me |
The company and the login the key acts as |
GET /v1/jobs |
Jobs, newest change first. Filters: status, updated_since (ISO date), limit (1 to 200, default 50), before |
GET /v1/jobs/{id} |
One job, by its id or its work order number |
GET /v1/customers |
Customers, newest first. Filters: updated_since, limit, before |
GET /v1/payments |
Payments, newest first. Filters: since (ISO date), limit, before |
Canceled jobs are never returned.
Add jobs, leads and notes
Needs a Read and add key (or a partner app connection from an office login).
| Endpoint | What it does |
|---|---|
POST /v1/jobs |
Adds a job. It starts as Submitted and shows in the Inbox |
POST /v1/leads |
Adds a lead: a Submitted job tagged New lead, unscheduled, in the Inbox. Answers {"status":"success", …} |
POST /v1/jobs/{id}/notes |
Adds a note to a job's history. {"text": "Customer called back, gate code 4411", "by": "Answering service"} |
curl -X POST https://app.dispatchmind.ai/v1/jobs \
-H "Authorization: Bearer dm_live_YOUR_KEY" -H "Content-Type: application/json" \
-d '{"customer": {"name": "Dana Whitfield", "phone": "3055550142", "email": "dana@example.com",
"address": "120 Bay Rd", "city": "Miami", "state": "FL", "zip": "33139"},
"service": "AC not cooling", "notes": "Upstairs unit",
"scheduled_start": "2026-10-06T09:00", "scheduled_end": "2026-10-06T12:00",
"source": "Office system", "external_id": "your-id-123", "tags": ["VIP"]}'
- Send a customer name or a phone, and a phone or an email.
scheduled_startandscheduled_endare local time at the job, with no time zone:2026-10-06T09:00.external_idmakes it safe to send the same job twice. A repeat answers200with"duplicate": trueand the job you already made.- The customer's fields can sit at the top level or under
customer. Common lead-feed names work too:firstName,lastName,primaryPhone,postalCode,stateProvince,taskName,comments,leadOid,interview.
A lead address for lead sources
Make a Lead address only key and DispatchMind gives you an address like:
https://app.dispatchmind.ai/v1/leads?source=Angi&key=dm_live_YOUR_LEAD_KEY
Give it to the lead source. Every lead it posts becomes a New lead job. A lead-address key can only add leads, and it's the only kind of key allowed in an address. Sources that send their key in a header (x-api-key or Authorization) can use the plain https://app.dispatchmind.ai/v1/leads?source=Angi instead.
Partner apps: Connect DispatchMind
Software partners connect with OAuth 2 (authorization code with PKCE, S256). DispatchMind registers each partner and its return addresses; write to support@dispatchmind.ai to get set up.
- Authorize:
https://app.dispatchmind.ai/oauth/authorize?client_id=…&redirect_uri=…&response_type=code&code_challenge=…&code_challenge_method=S256&state=…&resource=https://app.dispatchmind.ai/v1 - Token:
POST https://app.dispatchmind.ai/oauth/token(authorization_code, thenrefresh_token). Access tokens last 1 hour, refresh tokens 30 days. - Send the access token as
Authorization: Bearer …to any/v1endpoint. - The connection acts as the person who allowed it. Office logins can read and add; view-only logins can read; tech logins can't connect.
- Discovery:
https://app.dispatchmind.ai/.well-known/oauth-authorization-serverand/.well-known/oauth-protected-resource/v1.
Paging
Each list answer has data and next. When next is not null, ask again with before=<next> to get the next page.
{
"data": [ { "id": "…", "work_order": "1042", "status": "In progress", "customer_name": "James Carter", "total": 474, "balance_due": 0, "updated_at": "2026-10-02T14:05:11Z", … } ],
"next": "2026-10-02T13:58:40Z"
}
Limits and errors
- 120 requests a minute per key. Above that you get
429with aretry-afterheader. 401means the key is missing, wrong, revoked, or its login is switched off.404means no such record or endpoint.- Errors always come back as
{ "error": "plain words", "code": "short_code" }.
Webhooks
Add an https address under Manage API keys and webhooks. DispatchMind sends a POST within about a minute of a change, with these events:
job.createdjob.updatedpayment.received
The body holds up to 200 events:
{ "events": [ { "type": "job.updated", "at": "2026-10-02T14:05:11Z", "data": { "id": "…", "work_order": "1042", "status": "Done pending approval", … } } ],
"sent_at": "2026-10-02T14:05:40Z" }
Answer with any 2xx status. If your address fails, DispatchMind tries again every minute with the same changes. After 50 failures in a row the webhook pauses; add it again to restart.
Check the signature
Every webhook carries a DispatchMind-Signature header like t=1790950000,v1=5f2c…. The v1 value is an HMAC-SHA256 of t + "." + raw body, keyed with the webhook's signing secret (shown once when you add the webhook). Reject a message whose signature doesn't match, or whose t is more than 5 minutes old.
Node.js:
import crypto from 'node:crypto';
function verify(rawBody, header, secret) {
const parts = Object.fromEntries(header.split(',').map(p => p.split('=')));
const expected = crypto.createHmac('sha256', secret).update(parts.t + '.' + rawBody).digest('hex');
const fresh = Math.abs(Date.now() / 1000 - Number(parts.t)) < 300;
return fresh && crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(parts.v1));
}
Python:
import hmac, hashlib, time
def verify(raw_body: bytes, header: str, secret: str) -> bool:
parts = dict(p.split('=', 1) for p in header.split(','))
expected = hmac.new(secret.encode(), (parts['t'] + '.').encode() + raw_body, hashlib.sha256).hexdigest()
return abs(time.time() - int(parts['t'])) < 300 and hmac.compare_digest(expected, parts['v1'])
Questions
Can I create or change jobs through the API?
You can add jobs, leads and notes. Changing a job's status or deleting it isn't open through the API: jobs are never deleted in DispatchMind, and status moves stay with the office.
Is there an AI connector?
Yes. DispatchMind also works as a connector for Claude, through the same sign-in walls: look up jobs, customers and balances, and (for office logins) add a job, book or move a visit, assign the tech, tag, set the status or add a note. See the connector page.
Where do I see if the service is up?
The status page shows it, and https://app.dispatchmind.ai/status.json gives the same answer for your monitoring.