AllQuote API

Build on top of AllQuote — manage clients, jobs, quotes, invoices and payments over a simple JSON REST API, and receive real-time events via outbound webhooks. This is the same API used by our official Zapier integration.

Base URL
https://allquote.com.au/api/v1

All endpoints are served over HTTPS and return JSON. Authenticate every request with a Bearer token (see below). The API and webhooks are part of the Team and Business plans.

Authentication

The API uses bearer-token authentication. Send your API key in the Authorization header on every request:

Authorization: Bearer ak_your_api_key_here

Where to get your key. Sign in to AllQuote and open Settings → API & webhooks. Your key is shown there (Team and Business plans), and you can regenerate it at any time — regenerating immediately invalidates the old key.

Requests without a valid token receive 401 Unauthorized. Keep your key secret; treat it like a password. If your account is not on a plan that includes the API, write requests return 403 with plan_upgrade_required.

OAuth (connected apps)

Automation platforms such as Zapier connect via OAuth 2.0 rather than a static key. OAuth access tokens (prefixed at_) carry granular scopes — read:clients, write:clients, read:jobs, write:jobs, read:quotes, write:quotes, read:invoices, write:invoices — and a token is rejected with 403 insufficient_scope if it lacks the scope an endpoint needs. The static key from Settings carries full access and needs no scopes.

Errors

Errors are returned as JSON with an error field and the relevant HTTP status code:

{ "error": "not found" }
StatusMeaning
200 / 201Success. 201 is returned when a resource is created.
400Validation error (e.g. a required field is missing). The error field describes the problem.
401{"error":"invalid or missing API token"} — no valid Bearer token.
403Plan does not include the API (plan_upgrade_required) or the OAuth token lacks the required scope (insufficient_scope).
404The requested resource does not exist or is not in your account.

Rate limits

The API is intended for normal integration traffic (creating and reading records, recording payments). Please keep requests reasonable and avoid tight polling loops — use webhooks to receive changes in real time instead of polling. Excessive or abusive request volumes may be throttled.

A note on money & amounts

All monetary values are integers in cents (Australian dollars). For example $150.00 is 15000. GST is calculated automatically on quotes for GST-registered accounts.

Clients

GET/api/v1/clients

List clients, or search for a client. Optional query parameters: email, phone, search — supplying any of them filters the list (used by Zapier's "Find Client").

curl https://allquote.com.au/api/v1/[email protected] \
  -H "Authorization: Bearer ak_your_api_key_here"
{
  "clients": [
    {
      "id": 12,
      "name": "Jane Smith",
      "email": "[email protected]",
      "phone": "0400 000 000",
      "address": "1 George St, Sydney NSW"
    }
  ]
}
POST/api/v1/clients

Create a client. Body fields: name (required), email, phone, address. Returns the created client with 201. Fires the client.created webhook.

curl -X POST https://allquote.com.au/api/v1/clients \
  -H "Authorization: Bearer ak_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{"name":"Jane Smith","email":"[email protected]","phone":"0400 000 000","address":"1 George St, Sydney NSW"}'
{
  "id": 12,
  "name": "Jane Smith",
  "email": "[email protected]",
  "phone": "0400 000 000",
  "address": "1 George St, Sydney NSW"
}
POST/api/v1/clients/find-or-create

Idempotent client creation. Matches an existing client by email or phone; if none matches it creates one (supply at least a name, email, or phone). Returns {id, created, client}created is true only when a new client was made.

curl -X POST https://allquote.com.au/api/v1/clients/find-or-create \
  -H "Authorization: Bearer ak_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{"email":"[email protected]","name":"Jane Smith"}'
{
  "id": 12,
  "created": false,
  "client": { "id": 12, "name": "Jane Smith", "email": "[email protected]", "phone": "0400 000 000", "address": "" }
}
GET/api/v1/clients/{id}

Retrieve a single client by id.

curl https://allquote.com.au/api/v1/clients/12 \
  -H "Authorization: Bearer ak_your_api_key_here"
{ "id": 12, "name": "Jane Smith", "email": "[email protected]", "phone": "0400 000 000", "address": "1 George St, Sydney NSW" }
PATCH/api/v1/clients/{id}

Update a client. Send any of name, email, phone, address. Returns the updated client. Fires client.updated.

curl -X PATCH https://allquote.com.au/api/v1/clients/12 \
  -H "Authorization: Bearer ak_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{"phone":"0411 111 111"}'
{ "id": 12, "name": "Jane Smith", "email": "[email protected]", "phone": "0411 111 111", "address": "1 George St, Sydney NSW" }

Jobs

GET/api/v1/jobs

List jobs.

curl https://allquote.com.au/api/v1/jobs \
  -H "Authorization: Bearer ak_your_api_key_here"
{
  "jobs": [
    { "id": 7, "title": "Kitchen reno", "client_id": 12, "status": "scheduled",
      "address": "1 George St, Sydney NSW", "scheduled_date": "2026-07-01" }
  ]
}
POST/api/v1/jobs

Create a job. Body fields: title, client_id, address, notes, scheduled_date (all optional). Returns the created job with 201. Fires job.created.

curl -X POST https://allquote.com.au/api/v1/jobs \
  -H "Authorization: Bearer ak_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{"title":"Kitchen reno","client_id":12,"scheduled_date":"2026-07-01"}'
{ "id": 7, "title": "Kitchen reno", "client_id": 12, "status": "new",
  "address": "", "scheduled_date": "2026-07-01" }
GET/api/v1/jobs/{id}

Retrieve a single job by id.

curl https://allquote.com.au/api/v1/jobs/7 \
  -H "Authorization: Bearer ak_your_api_key_here"
PATCH/api/v1/jobs/{id}

Update a job. Accepted fields: title, address, status, scheduled_date, notes, assigned_to. Setting status to complete records the completion time and fires job.completed; any update also fires job.updated.

curl -X PATCH https://allquote.com.au/api/v1/jobs/7 \
  -H "Authorization: Bearer ak_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{"status":"complete"}'
{ "id": 7, "title": "Kitchen reno", "client_id": 12, "status": "complete",
  "address": "", "scheduled_date": "2026-07-01" }

Quotes

GET/api/v1/quotes

List quotes.

curl https://allquote.com.au/api/v1/quotes \
  -H "Authorization: Bearer ak_your_api_key_here"
{
  "quotes": [
    { "id": 33, "quote_number": "Q-1042", "title": "Kitchen reno", "status": "draft",
      "subtotal_cents": 150000, "gst_cents": 15000, "total_cents": 165000 }
  ]
}
POST/api/v1/quotes

Create a draft quote. Body fields: client_id, title, doc_type (quote or estimate), and line_items — an array of {description, qty, unit_price_cents}. Totals and GST (for GST-registered accounts) are computed for you. A substantive quote fires quote.created. Returns 201.

curl -X POST https://allquote.com.au/api/v1/quotes \
  -H "Authorization: Bearer ak_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "client_id": 12,
    "title": "Kitchen reno",
    "line_items": [
      {"description":"Labour","qty":8,"unit_price_cents":9000},
      {"description":"Materials","qty":1,"unit_price_cents":78000}
    ]
  }'
{
  "id": 33,
  "quote_number": "Q-1042",
  "title": "Kitchen reno",
  "status": "draft",
  "subtotal_cents": 150000,
  "gst_cents": 15000,
  "total_cents": 165000,
  "line_items": [
    {"description":"Labour","qty":8,"unit_price_cents":9000,"total_cents":72000,"category":"material"},
    {"description":"Materials","qty":1,"unit_price_cents":78000,"total_cents":78000,"category":"material"}
  ]
}
GET/api/v1/quotes/{id}

Retrieve a single quote by id.

curl https://allquote.com.au/api/v1/quotes/33 \
  -H "Authorization: Bearer ak_your_api_key_here"

Invoices & payments

GET/api/v1/invoices

List invoices.

curl https://allquote.com.au/api/v1/invoices \
  -H "Authorization: Bearer ak_your_api_key_here"
{
  "invoices": [
    { "id": 88, "title": "Kitchen reno", "client_id": 12, "status": "sent",
      "total_cents": 165000, "amount_paid_cents": 0, "due_date": "2026-07-15" }
  ]
}
POST/api/v1/invoices

Create an invoice. Body fields: client_id, title, due_date, and line_items — an array of {description, qty, unit_price_cents}. Totals are computed for you. Fires invoice.created. Returns 201.

curl -X POST https://allquote.com.au/api/v1/invoices \
  -H "Authorization: Bearer ak_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "client_id": 12,
    "title": "Kitchen reno",
    "due_date": "2026-07-15",
    "line_items": [ {"description":"Deposit","qty":1,"unit_price_cents":50000} ]
  }'
{ "id": 88, "title": "Kitchen reno", "client_id": 12, "status": "draft",
  "total_cents": 50000, "amount_paid_cents": 0, "due_date": "2026-07-15" }
GET/api/v1/invoices/{id}

Retrieve a single invoice by id.

curl https://allquote.com.au/api/v1/invoices/88 \
  -H "Authorization: Bearer ak_your_api_key_here"
POST/api/v1/invoices/{id}/payments

Record a payment against an invoice (Zapier's "Record Payment"). Body field: amount_cents (a positive integer). Progresses the invoice status, fires payment.received, and fires invoice.paid once the invoice is fully paid. Returns 201.

curl -X POST https://allquote.com.au/api/v1/invoices/88/payments \
  -H "Authorization: Bearer ak_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{"amount_cents":50000}'
{
  "id": 88,
  "amount_paid_cents": 50000,
  "total_cents": 50000,
  "fully_paid": true
}

Account

GET/api/v1/me

Return the authenticated account — handy for verifying a key or OAuth connection.

curl https://allquote.com.au/api/v1/me \
  -H "Authorization: Bearer ak_your_api_key_here"
{ "team_id": 4, "business_name": "Acme Plumbing" }

Webhooks

AllQuote can POST a signed JSON payload to a URL of your choice whenever something happens in your account — a "Catch Hook" in Zapier, or any HTTPS endpoint (Make.com, n8n, your own server). Add a webhook URL under Settings → API & webhooks, choosing which events it receives (or * for all events).

Events

EventFires when
quote.createdA new (substantive) quote is created.
quote.sentA quote is sent to a client.
quote.acceptedA client accepts a quote.
invoice.createdA new invoice is created.
invoice.paidAn invoice is fully paid.
payment.receivedA payment is recorded against an invoice.
job.createdA new job is created.
job.updatedA job is updated.
job.completedA job's status is set to complete.
client.createdA new client is created.
client.updatedA client is updated.
booking.createdA new booking is created.

Payload

Every webhook delivery is a POST with this JSON body:

{
  "event": "invoice.paid",
  "data": { "id": 88 },
  "ts": 1781827200
}

Delivery headers include X-AllQuote-Event (the event name) and a User-Agent of AllQuote-Webhook/1.0.

Verifying the signature

Each delivery carries an HMAC-SHA256 signature of the exact request body so you can confirm it came from AllQuote:

X-AllQuote-Signature: sha256=<hex digest>

Compute HMAC-SHA256(secret, raw_request_body) and compare the hex digest against the value after sha256=. For OAuth REST-Hook subscriptions the signing secret is unique per subscription and the delivery also includes an X-AllQuote-Subscription-Id header.

# Python example
import hmac, hashlib
expected = "sha256=" + hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
valid = hmac.compare_digest(expected, request.headers["X-AllQuote-Signature"])

Webhook delivery is best-effort and asynchronous: AllQuote attempts each delivery once with an 8-second timeout and does not block your in-app actions on it.

Need help?

Email [email protected] or connect AllQuote through our Zapier integration to automate without writing code.