REST API reference

Workiz API

15 endpoints for Workiz. Each one is a POST with a JSON body, called with your API key.

Base URL
https://cotlet.dev/api/v1/workiz
Connects with
Your own Workiz account (the permissions of your role apply)
Integration page
Workiz
Workiz Endpoints
Endpoint Access Description
list_jobs read Jobs by scheduled date, with status, client, address, assigned techs and amount due.
get_job read Full job: client, address, time window, job type, notes, items, total, amount due and payments.
get_schedule read Jobs and time off per technician for a day or range, as on the Workiz calendar.
list_leads read Leads with status, source, client details and assigned team member.
list_clients read Search clients by name, phone, email or address, with past jobs and balance due.
list_estimates read Estimates with client, total, status and the date they were sent.
list_invoices read Invoices with job, client, total, amount due and due date.
create_job write New job for an existing or new client, with job type, time window and notes.
reschedule_job write Move a job to a new time window. Changes the client's appointment.
assign_job write Assign or unassign team members on a job.
create_estimate write Draft estimate for a client with items from your Price Book. Nothing is sent yet.
send_estimate write Email or text an estimate to the client, with a link to approve it.
create_invoice write Invoice for a job with its items and total. Nothing is sent yet.
send_invoice write Email or text an invoice to the client, with a link to pay online.
record_payment write Record a payment you already received on a job. Does not charge a card.

List jobs

read

POST https://cotlet.dev/api/v1/workiz/list_jobs

Returns jobs in a date range, newest first, with status, client, address, assigned team members, total and amount due. Pages hold up to 100 jobs; pass next_cursor back as cursor for the next page. Filter by status or by team member to narrow the list.

Parameters

Parameters: list_jobs
NameTypeDescription
from date First scheduled date. Default: 14 days ago.
to date Last scheduled date. Default: today.
status string[] Job statuses to include, e.g. Submitted, In progress, Done, Canceled.
tech_id string Only jobs assigned to this team member.
limit integer 1 to 100. Default: 50.
cursor string Next page cursor from the previous call.

Request

cURL
curl -X POST https://cotlet.dev/api/v1/workiz/list_jobs \
  -H "Authorization: Bearer $COTLET_API_KEY"
Python
result = client.call("workiz", "list_jobs")
Node.js
const result = await cotlet.call('workiz', 'list_jobs');
CLI
cotlet call workiz list_jobs

Example response

{
  "jobs": [
    {
      "job_id": "7c1e5a90-2b4d-4f6e-9a31-0d8e2c4b6f17",
      "status": "Done",
      "job_type": "Water heater install",
      "scheduled_start": "2026-10-09T09:00:00-07:00",
      "client": {
        "client_id": "cl_5521",
        "name": "Dana Whitfield"
      },
      "address": "12 Oak St, Sacramento, CA",
      "techs": [
        "Mike R."
      ],
      "total": "480.00",
      "amount_due": "480.00"
    }
  ],
  "next_cursor": null
}

Get job

read

POST https://cotlet.dev/api/v1/workiz/get_job

Returns one job with everything on its page: client, address, time window, job type, notes, line items, total, amount due and the payments recorded so far. Use it before invoicing or recording a payment.

Parameters

Parameters: get_job
NameTypeDescription
job_id required string Job UUID from list_jobs.

Request

cURL
curl -X POST https://cotlet.dev/api/v1/workiz/get_job \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"job_id":"job_8c41d2"}'
Python
result = client.call("workiz", "get_job", {"job_id":"job_8c41d2"})
Node.js
const result = await cotlet.call('workiz', 'get_job', {"job_id":"job_8c41d2"});
CLI
cotlet call workiz get_job --data '{"job_id":"job_8c41d2"}'

Example response

{
  "job_id": "7c1e5a90-2b4d-4f6e-9a31-0d8e2c4b6f17",
  "status": "Done",
  "job_type": "Water heater install",
  "client": {
    "client_id": "cl_5521",
    "name": "Dana Whitfield",
    "phone": "(555) 010-2231"
  },
  "address": "12 Oak St, Sacramento, CA",
  "window": {
    "start": "2026-10-09T09:00:00-07:00",
    "end": "2026-10-09T11:00:00-07:00"
  },
  "notes": "Gas line on the left wall.",
  "items": [
    {
      "name": "40 gal water heater",
      "quantity": 1,
      "price": "380.00"
    },
    {
      "name": "Install labor",
      "quantity": 1,
      "price": "100.00"
    }
  ],
  "total": "480.00",
  "amount_due": "480.00",
  "payments": []
}

POST https://cotlet.dev/api/v1/workiz/get_schedule

Returns each team member with their jobs and time off for the days you ask, ordered by start time, so your agent can see who has open slots. Time off is the future time off set in Workiz.

Parameters

Parameters: get_schedule
NameTypeDescription
from required date First day.
to date Last day. Default: same as from.
tech_ids string[] Limit to these team members. Default: everyone.

Request

cURL
curl -X POST https://cotlet.dev/api/v1/workiz/get_schedule \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"from":"2026-10-01"}'
Python
result = client.call("workiz", "get_schedule", {"from":"2026-10-01"})
Node.js
const result = await cotlet.call('workiz', 'get_schedule', {"from":"2026-10-01"});
CLI
cotlet call workiz get_schedule --data '{"from":"2026-10-01"}'

Example response

{
  "days": [
    {
      "date": "2026-10-12",
      "techs": [
        {
          "tech_id": "u_204",
          "name": "Mike R.",
          "jobs": [
            {
              "job_id": "3a9d41f2-85c0-4b7e-b6d2-91e7f0a35c48",
              "start": "2026-10-12T09:00:00-07:00",
              "end": "2026-10-12T11:00:00-07:00",
              "job_type": "Drain cleaning"
            }
          ],
          "time_off": []
        }
      ]
    }
  ]
}

List leads

read

POST https://cotlet.dev/api/v1/workiz/list_leads

Returns leads, newest first, with status, source, contact details and the assigned team member. Open is the default, so converted and lost leads appear only when you ask for them. Pages hold up to 100 leads.

Parameters

Parameters: list_leads
NameTypeDescription
status enum open, converted or lost. Default: open.
since date Only leads created on or after this date.
limit integer 1 to 100. Default: 50.

Request

cURL
curl -X POST https://cotlet.dev/api/v1/workiz/list_leads \
  -H "Authorization: Bearer $COTLET_API_KEY"
Python
result = client.call("workiz", "list_leads")
Node.js
const result = await cotlet.call('workiz', 'list_leads');
CLI
cotlet call workiz list_leads

Example response

{
  "leads": [
    {
      "lead_id": "ld_8841",
      "status": "open",
      "source": "Website",
      "name": "Priya Nair",
      "phone": "(555) 010-7714",
      "created_at": "2026-10-10T08:12:00-07:00",
      "assigned_to": null
    }
  ],
  "next_cursor": null
}

POST https://cotlet.dev/api/v1/workiz/list_clients

Searches your Workiz clients and returns matches with contact details, their past jobs and the balance due. Use the client_id in create_job, create_estimate and the other tools.

Parameters

Parameters: list_clients
NameTypeDescription
query string Name, phone, email or address.
limit integer 1 to 100. Default: 25.

Request

cURL
curl -X POST https://cotlet.dev/api/v1/workiz/list_clients \
  -H "Authorization: Bearer $COTLET_API_KEY"
Python
result = client.call("workiz", "list_clients")
Node.js
const result = await cotlet.call('workiz', 'list_clients');
CLI
cotlet call workiz list_clients

Example response

{
  "clients": [
    {
      "client_id": "cl_5521",
      "name": "Dana Whitfield",
      "phone": "(555) 010-2231",
      "email": "dana@example.com",
      "address": "12 Oak St, Sacramento, CA",
      "jobs": 3,
      "balance_due": "480.00"
    }
  ]
}

POST https://cotlet.dev/api/v1/workiz/list_estimates

Returns estimates, newest first, with client, total, status and the date sent. Filter by status to find the ones still waiting for an answer. Pages hold up to 100 estimates.

Parameters

Parameters: list_estimates
NameTypeDescription
status enum draft, sent, approved or declined. Default: all.
since date Only estimates created on or after this date.
limit integer 1 to 100. Default: 50.

Request

cURL
curl -X POST https://cotlet.dev/api/v1/workiz/list_estimates \
  -H "Authorization: Bearer $COTLET_API_KEY"
Python
result = client.call("workiz", "list_estimates")
Node.js
const result = await cotlet.call('workiz', 'list_estimates');
CLI
cotlet call workiz list_estimates

Example response

{
  "estimates": [
    {
      "estimate_id": "est_1187",
      "client": "Priya Nair",
      "total": "1,250.00",
      "status": "sent",
      "sent_at": "2026-10-01T10:15:00-07:00"
    }
  ],
  "next_cursor": null
}

POST https://cotlet.dev/api/v1/workiz/list_invoices

Returns invoices, newest first, with the job, client, total, amount due and due date. Unpaid is the default. Pages hold up to 100 invoices.

Parameters

Parameters: list_invoices
NameTypeDescription
status enum unpaid, partially_paid or paid. Default: unpaid.
since date Only invoices created on or after this date.
limit integer 1 to 100. Default: 50.

Request

cURL
curl -X POST https://cotlet.dev/api/v1/workiz/list_invoices \
  -H "Authorization: Bearer $COTLET_API_KEY"
Python
result = client.call("workiz", "list_invoices")
Node.js
const result = await cotlet.call('workiz', 'list_invoices');
CLI
cotlet call workiz list_invoices

Example response

{
  "invoices": [
    {
      "invoice_id": "inv_30214",
      "job_id": "7c1e5a90-2b4d-4f6e-9a31-0d8e2c4b6f17",
      "client": "Dana Whitfield",
      "total": "480.00",
      "amount_due": "240.00",
      "due_date": "2026-10-23",
      "status": "partially_paid"
    }
  ],
  "next_cursor": null
}

Create job

write Confirm

POST https://cotlet.dev/api/v1/workiz/create_job

Creates a job for an existing client (client_id) or a new one (client object). Job type must be one of your Workiz job types. The job books an appointment for the client at the time you give. Returns the new job_id. By default you confirm each call; you can switch that off for this tool.

Parameters

Parameters: create_job
NameTypeDescription
client_id string Existing client from list_clients. Or pass client below.
client object New client: first_name, last_name, phone, email, address.
job_type required string One of your Workiz job types.
start required datetime ISO 8601 with time zone.
end datetime End of the time window.
notes string Job notes for the tech.

Request

cURL
curl -X POST https://cotlet.dev/api/v1/workiz/create_job \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"client_id":"cl_5521","job_type":"Water heater install","start":"2026-10-14T09:00:00-07:00","end":"2026-10-14T11:00:00-07:00","notes":"From lead ld_8841: tank leaking at the base."}'
Python
result = client.call("workiz", "create_job", {"client_id":"cl_5521","job_type":"Water heater install","start":"2026-10-14T09:00:00-07:00","end":"2026-10-14T11:00:00-07:00","notes":"From lead ld_8841: tank leaking at the base."})
Node.js
const result = await cotlet.call('workiz', 'create_job', {"client_id":"cl_5521","job_type":"Water heater install","start":"2026-10-14T09:00:00-07:00","end":"2026-10-14T11:00:00-07:00","notes":"From lead ld_8841: tank leaking at the base."});
CLI
cotlet call workiz create_job --data '{"client_id":"cl_5521","job_type":"Water heater install","start":"2026-10-14T09:00:00-07:00","end":"2026-10-14T11:00:00-07:00","notes":"From lead ld_8841: tank leaking at the base."}'

Example response

{
  "job_id": "9e2b7d14-6c35-4a08-8f1d-3b5a0c7e92d6",
  "status": "Submitted",
  "job_type": "Water heater install",
  "client_id": "cl_5521",
  "start": "2026-10-16T09:00:00-07:00",
  "notes": "Gas line on the left wall."
}

Reschedule job

write Confirm

POST https://cotlet.dev/api/v1/workiz/reschedule_job

Moves one job to a new start and, if given, a new end. The job keeps its assigned team members and its status. By default you confirm each call; you can switch that off for this tool.

Parameters

Parameters: reschedule_job
NameTypeDescription
job_id required string Job UUID from list_jobs.
start required datetime New start, ISO 8601 with time zone.
end datetime New end.

Request

cURL
curl -X POST https://cotlet.dev/api/v1/workiz/reschedule_job \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"job_id":"3a9d41f2-85c0-4b7e-b6d2-91e7f0a35c48","start":"2026-10-13T09:00:00-07:00","end":"2026-10-13T11:00:00-07:00"}'
Python
result = client.call("workiz", "reschedule_job", {"job_id":"3a9d41f2-85c0-4b7e-b6d2-91e7f0a35c48","start":"2026-10-13T09:00:00-07:00","end":"2026-10-13T11:00:00-07:00"})
Node.js
const result = await cotlet.call('workiz', 'reschedule_job', {"job_id":"3a9d41f2-85c0-4b7e-b6d2-91e7f0a35c48","start":"2026-10-13T09:00:00-07:00","end":"2026-10-13T11:00:00-07:00"});
CLI
cotlet call workiz reschedule_job --data '{"job_id":"3a9d41f2-85c0-4b7e-b6d2-91e7f0a35c48","start":"2026-10-13T09:00:00-07:00","end":"2026-10-13T11:00:00-07:00"}'

Example response

{
  "job_id": "3a9d41f2-85c0-4b7e-b6d2-91e7f0a35c48",
  "status": "Submitted",
  "start": "2026-10-13T09:00:00-07:00",
  "end": "2026-10-13T11:00:00-07:00",
  "previous_start": "2026-10-12T09:00:00-07:00"
}

Assign job

write

POST https://cotlet.dev/api/v1/workiz/assign_job

Adds team members to a job, or replaces the current ones when replace is true. It runs without asking first: it sends nothing to the client and one more call changes the assignment back.

Parameters

Parameters: assign_job
NameTypeDescription
job_id required string Job UUID from list_jobs.
tech_ids required string[] Team members to assign.
replace boolean Remove current assignees first. Default: false.

Request

cURL
curl -X POST https://cotlet.dev/api/v1/workiz/assign_job \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"job_id":"job_8c41d2","tech_ids":["tech ids"]}'
Python
result = client.call("workiz", "assign_job", {"job_id":"job_8c41d2","tech_ids":["tech ids"]})
Node.js
const result = await cotlet.call('workiz', 'assign_job', {"job_id":"job_8c41d2","tech_ids":["tech ids"]});
CLI
cotlet call workiz assign_job --data '{"job_id":"job_8c41d2","tech_ids":["tech ids"]}'

Example response

{
  "job_id": "7c1e5a90-2b4d-4f6e-9a31-0d8e2c4b6f17",
  "techs": [
    {
      "tech_id": "u_204",
      "name": "Mike R."
    }
  ]
}

POST https://cotlet.dev/api/v1/workiz/create_estimate

Creates an estimate in Draft for one client. Item names match items in your Workiz Price Book. Nothing is sent to the client until send_estimate runs, so this call runs without asking.

Parameters

Parameters: create_estimate
NameTypeDescription
client_id required string Client from list_clients.
items required object List of {name, quantity, price}; names match Price Book items.
notes string Note shown to the client.

Request

cURL
curl -X POST https://cotlet.dev/api/v1/workiz/create_estimate \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"client_id":"client_8c41d2","items":"items"}'
Python
result = client.call("workiz", "create_estimate", {"client_id":"client_8c41d2","items":"items"})
Node.js
const result = await cotlet.call('workiz', 'create_estimate', {"client_id":"client_8c41d2","items":"items"});
CLI
cotlet call workiz create_estimate --data '{"client_id":"client_8c41d2","items":"items"}'

Example response

{
  "estimate_id": "est_1192",
  "client_id": "cl_5521",
  "status": "draft",
  "items": [
    {
      "name": "Tankless water heater",
      "quantity": 1,
      "price": "1,250.00"
    }
  ],
  "total": "1,250.00"
}

Send estimate

write Confirm

POST https://cotlet.dev/api/v1/workiz/send_estimate

Sends the estimate by email, text or both, with a link to view and approve it in the Workiz client portal. An unsent estimate becomes Pending; approval in the portal moves it to Approved. By default you confirm each call; you can switch that off for this tool.

Parameters

Parameters: send_estimate
NameTypeDescription
estimate_id required string Estimate from list_estimates or create_estimate.
via enum email, sms or both. Default: email.

Request

cURL
curl -X POST https://cotlet.dev/api/v1/workiz/send_estimate \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"estimate_id":"estimate_8c41d2"}'
Python
result = client.call("workiz", "send_estimate", {"estimate_id":"estimate_8c41d2"})
Node.js
const result = await cotlet.call('workiz', 'send_estimate', {"estimate_id":"estimate_8c41d2"});
CLI
cotlet call workiz send_estimate --data '{"estimate_id":"estimate_8c41d2"}'

Example response

{
  "estimate_id": "est_1187",
  "status": "pending",
  "sent_via": "email",
  "sent_at": "2026-10-11T09:00:00-07:00"
}

POST https://cotlet.dev/api/v1/workiz/create_invoice

Creates an invoice from a job, with the job's items and total. Nothing is sent to the client until send_invoice runs, so this call runs without asking. Returns the invoice_id.

Parameters

Parameters: create_invoice
NameTypeDescription
job_id required string Job UUID from list_jobs.
due_date date Payment due date.

Request

cURL
curl -X POST https://cotlet.dev/api/v1/workiz/create_invoice \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"job_id":"job_8c41d2"}'
Python
result = client.call("workiz", "create_invoice", {"job_id":"job_8c41d2"})
Node.js
const result = await cotlet.call('workiz', 'create_invoice', {"job_id":"job_8c41d2"});
CLI
cotlet call workiz create_invoice --data '{"job_id":"job_8c41d2"}'

Example response

{
  "invoice_id": "inv_30214",
  "job_id": "7c1e5a90-2b4d-4f6e-9a31-0d8e2c4b6f17",
  "items": [
    {
      "name": "40 gal water heater",
      "quantity": 1,
      "price": "380.00"
    },
    {
      "name": "Install labor",
      "quantity": 1,
      "price": "100.00"
    }
  ],
  "total": "480.00",
  "amount_due": "480.00",
  "due_date": "2026-10-23",
  "status": "unsent"
}

Send invoice

write Confirm

POST https://cotlet.dev/api/v1/workiz/send_invoice

Sends the invoice by email, text or both, with a link to the Workiz client portal. The client sees the amount due there. By default you confirm each call; you can switch that off for this tool.

Parameters

Parameters: send_invoice
NameTypeDescription
invoice_id required string Invoice from list_invoices or create_invoice.
via enum email, sms or both. Default: email.

Request

cURL
curl -X POST https://cotlet.dev/api/v1/workiz/send_invoice \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"invoice_id":"inv_30214","via":"email"}'
Python
result = client.call("workiz", "send_invoice", {"invoice_id":"inv_30214","via":"email"})
Node.js
const result = await cotlet.call('workiz', 'send_invoice', {"invoice_id":"inv_30214","via":"email"});
CLI
cotlet call workiz send_invoice --data '{"invoice_id":"inv_30214","via":"email"}'

Example response

{
  "invoice_id": "inv_30214",
  "status": "sent",
  "sent_via": "email",
  "amount_due": "480.00",
  "sent_at": "2026-10-11T18:00:00-07:00"
}

Record payment

write Confirm

POST https://cotlet.dev/api/v1/workiz/record_payment

Records a payment you already received on a job, as cash, check or credit, with an optional reference such as a check number. It does not charge a card. Returns the job total and the amount still due. By default you confirm each call; you can switch that off for this tool.

Parameters

Parameters: record_payment
NameTypeDescription
job_id required string Job UUID from list_jobs.
amount required string Amount, e.g. 240.00.
method required enum cash, check or credit.
paid_at datetime When it was paid. Default: now.
reference string Check number or confirmation number.

Request

cURL
curl -X POST https://cotlet.dev/api/v1/workiz/record_payment \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"job_id":"7c1e5a90-2b4d-4f6e-9a31-0d8e2c4b6f17","amount":"240.00","method":"check","paid_at":"2026-10-09T15:30:00-07:00","reference":"1042"}'
Python
result = client.call("workiz", "record_payment", {"job_id":"7c1e5a90-2b4d-4f6e-9a31-0d8e2c4b6f17","amount":"240.00","method":"check","paid_at":"2026-10-09T15:30:00-07:00","reference":"1042"})
Node.js
const result = await cotlet.call('workiz', 'record_payment', {"job_id":"7c1e5a90-2b4d-4f6e-9a31-0d8e2c4b6f17","amount":"240.00","method":"check","paid_at":"2026-10-09T15:30:00-07:00","reference":"1042"});
CLI
cotlet call workiz record_payment --data '{"job_id":"7c1e5a90-2b4d-4f6e-9a31-0d8e2c4b6f17","amount":"240.00","method":"check","paid_at":"2026-10-09T15:30:00-07:00","reference":"1042"}'

Example response

{
  "job_id": "7c1e5a90-2b4d-4f6e-9a31-0d8e2c4b6f17",
  "payment_id": "pay_88213",
  "amount": "240.00",
  "method": "check",
  "reference": "1042",
  "job_total": "480.00",
  "amount_due": "240.00",
  "status": "recorded"
}