REST API reference
Yardbook API
14 endpoints for Yardbook. Each one is a POST with a JSON body, called with your API key.
- Base URL
- https://cotlet.dev/api/v1/yardbook
- Connects with
- Your own Yardbook account (email and password, the account owner or an office user)
- Integration page
- Yardbook
| Endpoint | Access | Description |
|---|---|---|
| list_customers | read | Customers and prospects with address, email, phone and balance. |
| get_customer | read | One customer with contact details, notes, upcoming jobs, open estimates and invoices. |
| list_jobs | read | Scheduled and completed jobs in a date range, with customer, services and assigned crew member. |
| list_estimates | read | Estimates with customer, total and status, newest first. |
| list_invoices | read | Invoices with customer, total, amount due, due date and status. |
| get_invoice | read | Full invoice: line items, payments recorded and amount due. |
| create_customer | write | Add a customer or prospect with contact details and service address. |
| schedule_job | write | Add a one-time or recurring job to the schedule, optionally assigned to a crew member. |
| complete_job | write | Mark a job as completed, so it can be invoiced. |
| create_estimate | write | Draft estimate for a customer or prospect. Nothing is sent until you call send_estimate. |
| send_estimate | write | Email an estimate to the customer with a link to approve it online. |
| create_invoice | write | Invoice from a completed job or an approved estimate, or with your own line items. Not sent yet. |
| send_invoice | write | Email an invoice to the customer with a link to view it. |
| record_payment | write | Record a cash, check or other payment received against an invoice. |
List customers
readPOST https://cotlet.dev/api/v1/yardbook/list_customers
Lists customers, prospects or both. Search matches name, address, email and phone. Balance is the amount the customer still owes on open invoices. Pass next_cursor back as cursor for the next page.
Parameters
| Name | Type | Description |
|---|---|---|
| type | enum | customer, prospect or all. Default: customer. |
| search | string | Match on name, address, email or phone. |
| limit | integer | 1 to 200. Default: 50. |
| cursor | string | Next page cursor from the previous call. |
Request
curl -X POST https://cotlet.dev/api/v1/yardbook/list_customers \
-H "Authorization: Bearer $COTLET_API_KEY" result = client.call("yardbook", "list_customers") const result = await cotlet.call('yardbook', 'list_customers'); cotlet call yardbook list_customers Example response
{
"customers": [
{
"customer_id": "284117",
"name": "Maria Lopez",
"type": "customer",
"address": "18 Elm Street",
"email": "maria@example.com",
"phone": "555-0142",
"balance": "0.00"
},
{
"customer_id": "284230",
"name": "Parker Property",
"type": "customer",
"address": "7 Ridge Road",
"email": "office@parker.example.com",
"phone": "555-0177",
"balance": "240.00"
}
],
"next_cursor": null
} Get customer
readPOST https://cotlet.dev/api/v1/yardbook/get_customer
Returns one customer with contact details and property notes, plus their upcoming jobs, open estimates and unpaid invoices. Use it before scheduling or billing so your agent sees what is already there.
Parameters
| Name | Type | Description |
|---|---|---|
| customer_id required | string | Customer ID from list_customers. |
Request
curl -X POST https://cotlet.dev/api/v1/yardbook/get_customer \
-H "Authorization: Bearer $COTLET_API_KEY" \
-H "Content-Type: application/json" \
-d '{"customer_id":"customer_8c41d2"}' result = client.call("yardbook", "get_customer", {"customer_id":"customer_8c41d2"}) const result = await cotlet.call('yardbook', 'get_customer', {"customer_id":"customer_8c41d2"}); cotlet call yardbook get_customer --data '{"customer_id":"customer_8c41d2"}' Example response
{
"customer_id": "284117",
"name": "Maria Lopez",
"type": "customer",
"address": "18 Elm Street",
"notes": "Side gate code 1234. Dog in yard.",
"upcoming_jobs": [
{
"job_id": "9930412",
"date": "2026-10-13",
"services": [
"Mowing",
"Edging"
]
}
],
"open_estimates": [],
"unpaid_invoices": []
} List jobs
readPOST https://cotlet.dev/api/v1/yardbook/list_jobs
Lists jobs between two dates, oldest first, with customer, services and the crew member each job is assigned to. Filter by status, crew member or customer. Recurring jobs appear as one entry per visit in the range.
Parameters
| Name | Type | Description |
|---|---|---|
| from required | date | First day of the range. |
| to required | date | Last day of the range. |
| status | enum | scheduled, completed or all. Default: all. |
| assignee_id | string | Only jobs assigned to this crew member. |
| customer_id | string | Only jobs for this customer. |
Request
curl -X POST https://cotlet.dev/api/v1/yardbook/list_jobs \
-H "Authorization: Bearer $COTLET_API_KEY" \
-H "Content-Type: application/json" \
-d '{"from":"2026-10-01","to":"2026-10-01"}' result = client.call("yardbook", "list_jobs", {"from":"2026-10-01","to":"2026-10-01"}) const result = await cotlet.call('yardbook', 'list_jobs', {"from":"2026-10-01","to":"2026-10-01"}); cotlet call yardbook list_jobs --data '{"from":"2026-10-01","to":"2026-10-01"}' Example response
{
"jobs": [
{
"job_id": "9930412",
"date": "2026-10-13",
"customer_id": "284117",
"customer": "Maria Lopez",
"services": [
"Mowing",
"Edging"
],
"status": "scheduled",
"assignee": "Crew 1"
},
{
"job_id": "9930455",
"date": "2026-10-13",
"customer_id": "284230",
"customer": "Parker Property",
"services": [
"Spring cleanup"
],
"status": "scheduled",
"assignee": "Crew 2"
}
]
} List estimates
readPOST https://cotlet.dev/api/v1/yardbook/list_estimates
Lists estimates newest first with customer, total and status. Draft estimates have not been sent. Approved estimates can be turned into an invoice with create_invoice.
Parameters
| Name | Type | Description |
|---|---|---|
| status | enum | draft, sent, approved or all. Default: all. |
| customer_id | string | Only estimates for this customer. |
| limit | integer | 1 to 100. Default: 50. |
Request
curl -X POST https://cotlet.dev/api/v1/yardbook/list_estimates \
-H "Authorization: Bearer $COTLET_API_KEY" result = client.call("yardbook", "list_estimates") const result = await cotlet.call('yardbook', 'list_estimates'); cotlet call yardbook list_estimates Example response
{
"estimates": [
{
"estimate_id": "51802",
"customer_id": "284230",
"customer": "Parker Property",
"total": "490.00",
"status": "draft",
"created_at": "2026-10-09"
}
]
} List invoices
readPOST https://cotlet.dev/api/v1/yardbook/list_invoices
Lists invoices newest first. Status defaults to unpaid. Amount due is the total minus the payments recorded. older_than_days keeps invoices issued at least that many days ago, which is how you find overdue ones.
Parameters
| Name | Type | Description |
|---|---|---|
| status | enum | unpaid, paid or all. Default: unpaid. |
| customer_id | string | Only invoices for this customer. |
| older_than_days | integer | Only invoices issued at least this many days ago. |
| limit | integer | 1 to 100. Default: 50. |
Request
curl -X POST https://cotlet.dev/api/v1/yardbook/list_invoices \
-H "Authorization: Bearer $COTLET_API_KEY" result = client.call("yardbook", "list_invoices") const result = await cotlet.call('yardbook', 'list_invoices'); cotlet call yardbook list_invoices Example response
{
"invoices": [
{
"invoice_id": "73194",
"customer_id": "284230",
"customer": "Parker Property",
"issued_at": "2026-09-02",
"due_date": "2026-09-16",
"total": "240.00",
"amount_due": "240.00",
"status": "unpaid"
}
]
} Get invoice
readPOST https://cotlet.dev/api/v1/yardbook/get_invoice
Returns one invoice with every line item, the payments recorded against it and the amount due. Use it to check an invoice before sending it or recording a payment.
Parameters
| Name | Type | Description |
|---|---|---|
| invoice_id required | string | Invoice ID from list_invoices. |
Request
curl -X POST https://cotlet.dev/api/v1/yardbook/get_invoice \
-H "Authorization: Bearer $COTLET_API_KEY" \
-H "Content-Type: application/json" \
-d '{"invoice_id":"invoice_8c41d2"}' result = client.call("yardbook", "get_invoice", {"invoice_id":"invoice_8c41d2"}) const result = await cotlet.call('yardbook', 'get_invoice', {"invoice_id":"invoice_8c41d2"}); cotlet call yardbook get_invoice --data '{"invoice_id":"invoice_8c41d2"}' Example response
{
"invoice_id": "73194",
"customer": "Parker Property",
"status": "unpaid",
"line_items": [
{
"service": "Mowing",
"description": "Weekly mowing, September",
"quantity": 4,
"unit_price": "60.00"
}
],
"total": "240.00",
"payments": [],
"amount_due": "240.00"
} Create customer
writePOST https://cotlet.dev/api/v1/yardbook/create_customer
Adds a customer, or a prospect if type is prospect, with the service address and contact details. It reaches no one and changes only your customer list, so it runs without asking for your OK.
Parameters
| Name | Type | Description |
|---|---|---|
| name required | string | Customer or company name. |
| address required | string | Service address. |
| string | Email for estimates and invoices. | |
| phone | string | Phone number. |
| type | enum | customer or prospect. Default: customer. |
| notes | string | Gate codes, pets, property notes. |
Request
curl -X POST https://cotlet.dev/api/v1/yardbook/create_customer \
-H "Authorization: Bearer $COTLET_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"Jane Doe","address":"address"}' result = client.call("yardbook", "create_customer", {"name":"Jane Doe","address":"address"}) const result = await cotlet.call('yardbook', 'create_customer', {"name":"Jane Doe","address":"address"}); cotlet call yardbook create_customer --data '{"name":"Jane Doe","address":"address"}' Example response
{
"customer_id": "284117",
"name": "Maria Lopez",
"type": "customer",
"address": "18 Elm Street"
} Schedule job
writePOST https://cotlet.dev/api/v1/yardbook/schedule_job
Adds a job for a customer on the date of the first visit. With repeat set to weekly or biweekly it creates a recurring job. Services are names from your product and service catalog. It sends nothing to the customer, so it runs without asking for your OK.
Parameters
| Name | Type | Description |
|---|---|---|
| customer_id required | string | Customer ID from list_customers. |
| date required | date | Date of the first visit. |
| services required | string[] | Services from your product catalog, e.g. Mowing. |
| repeat | enum | none, weekly or biweekly. Default: none. |
| assignee_id | string | Crew member to assign. |
| notes | string | Instructions for the crew. |
Request
curl -X POST https://cotlet.dev/api/v1/yardbook/schedule_job \
-H "Authorization: Bearer $COTLET_API_KEY" \
-H "Content-Type: application/json" \
-d '{"customer_id":"284117","date":"2026-10-13","services":["Mowing","Edging"],"repeat":"weekly","assignee_id":"5521","notes":"Side gate code 1234. Bag clippings."}' result = client.call("yardbook", "schedule_job", {"customer_id":"284117","date":"2026-10-13","services":["Mowing","Edging"],"repeat":"weekly","assignee_id":"5521","notes":"Side gate code 1234. Bag clippings."}) const result = await cotlet.call('yardbook', 'schedule_job', {"customer_id":"284117","date":"2026-10-13","services":["Mowing","Edging"],"repeat":"weekly","assignee_id":"5521","notes":"Side gate code 1234. Bag clippings."}); cotlet call yardbook schedule_job --data '{"customer_id":"284117","date":"2026-10-13","services":["Mowing","Edging"],"repeat":"weekly","assignee_id":"5521","notes":"Side gate code 1234. Bag clippings."}' Example response
{
"job_id": "9930412",
"customer_id": "284117",
"date": "2026-10-13",
"repeat": "weekly",
"status": "scheduled",
"services": [
"Mowing",
"Edging"
],
"assignee": "Crew 1"
} Complete job
writePOST https://cotlet.dev/api/v1/yardbook/complete_job
Marks one job completed, with optional notes on what was done. A completed job can be passed to create_invoice. It sends nothing to the customer, so it runs without asking for your OK.
Parameters
| Name | Type | Description |
|---|---|---|
| job_id required | string | Job ID from list_jobs. |
| notes | string | What was done on site. |
Request
curl -X POST https://cotlet.dev/api/v1/yardbook/complete_job \
-H "Authorization: Bearer $COTLET_API_KEY" \
-H "Content-Type: application/json" \
-d '{"job_id":"job_8c41d2"}' result = client.call("yardbook", "complete_job", {"job_id":"job_8c41d2"}) const result = await cotlet.call('yardbook', 'complete_job', {"job_id":"job_8c41d2"}); cotlet call yardbook complete_job --data '{"job_id":"job_8c41d2"}' Example response
{
"job_id": "9930412",
"status": "completed",
"notes": "Mowed and edged, bagged clippings."
} Create estimate
writePOST https://cotlet.dev/api/v1/yardbook/create_estimate
Saves a draft estimate with your line items. The total is the sum of quantity times unit_price over all lines. Nothing is sent to the customer until send_estimate, so the draft runs without asking for your OK.
Parameters
| Name | Type | Description |
|---|---|---|
| customer_id required | string | Customer ID from list_customers. |
| line_items required | object[] | List of { service, description, quantity, unit_price }. |
| description | string | Scope of work shown on the estimate. |
Request
curl -X POST https://cotlet.dev/api/v1/yardbook/create_estimate \
-H "Authorization: Bearer $COTLET_API_KEY" \
-H "Content-Type: application/json" \
-d '{"customer_id":"284230","description":"Spring cleanup, mulch and shrub trimming","line_items":[{"service":"Spring cleanup","description":"Leaf removal and cleanup of all beds","quantity":1,"unit_price":"220.00"},{"service":"Mulch","description":"Hardwood mulch, installed","quantity":6,"unit_price":"45.00"},{"service":"Shrub trimming","description":"Boxwoods along the walk","quantity":4,"unit_price":"15.00"}]}' result = client.call("yardbook", "create_estimate", {"customer_id":"284230","description":"Spring cleanup, mulch and shrub trimming","line_items":[{"service":"Spring cleanup","description":"Leaf removal and cleanup of all beds","quantity":1,"unit_price":"220.00"},{"service":"Mulch","description":"Hardwood mulch, installed","quantity":6,"unit_price":"45.00"},{"service":"Shrub trimming","description":"Boxwoods along the walk","quantity":4,"unit_price":"15.00"}]}) const result = await cotlet.call('yardbook', 'create_estimate', {"customer_id":"284230","description":"Spring cleanup, mulch and shrub trimming","line_items":[{"service":"Spring cleanup","description":"Leaf removal and cleanup of all beds","quantity":1,"unit_price":"220.00"},{"service":"Mulch","description":"Hardwood mulch, installed","quantity":6,"unit_price":"45.00"},{"service":"Shrub trimming","description":"Boxwoods along the walk","quantity":4,"unit_price":"15.00"}]}); cotlet call yardbook create_estimate --data '{"customer_id":"284230","description":"Spring cleanup, mulch and shrub trimming","line_items":[{"service":"Spring cleanup","description":"Leaf removal and cleanup of all beds","quantity":1,"unit_price":"220.00"},{"service":"Mulch","description":"Hardwood mulch, installed","quantity":6,"unit_price":"45.00"},{"service":"Shrub trimming","description":"Boxwoods along the walk","quantity":4,"unit_price":"15.00"}]}' Example response
{
"estimate_id": "51802",
"customer_id": "284117",
"status": "draft",
"line_items": [
{
"service": "Spring cleanup",
"quantity": 1,
"unit_price": "220.00",
"amount": "220.00"
},
{
"service": "Mulch",
"quantity": 6,
"unit_price": "45.00",
"amount": "270.00"
}
],
"total": "490.00"
} POST https://cotlet.dev/api/v1/yardbook/send_estimate
Emails a draft estimate to the customer, with your optional note and a link to approve it online. The customer needs an email address on file. By default you confirm each call; you can switch that off for this tool.
Parameters
| Name | Type | Description |
|---|---|---|
| estimate_id required | string | Estimate ID from list_estimates. |
| message | string | Note added to the email. |
Request
curl -X POST https://cotlet.dev/api/v1/yardbook/send_estimate \
-H "Authorization: Bearer $COTLET_API_KEY" \
-H "Content-Type: application/json" \
-d '{"estimate_id":"estimate_8c41d2"}' result = client.call("yardbook", "send_estimate", {"estimate_id":"estimate_8c41d2"}) const result = await cotlet.call('yardbook', 'send_estimate', {"estimate_id":"estimate_8c41d2"}); cotlet call yardbook send_estimate --data '{"estimate_id":"estimate_8c41d2"}' Example response
{
"estimate_id": "51802",
"status": "sent",
"sent_to": "maria@example.com"
} Create invoice
writePOST https://cotlet.dev/api/v1/yardbook/create_invoice
Creates an invoice from a completed job, from an approved estimate, or from line items you pass. It is saved unsent; send_invoice emails it. It reaches no one, so it runs without asking for your OK.
Parameters
| Name | Type | Description |
|---|---|---|
| customer_id required | string | Customer ID from list_customers. |
| job_id | string | Completed job to invoice. |
| estimate_id | string | Approved estimate to convert. |
| line_items | object[] | List of { service, description, quantity, unit_price }, when there is no job or estimate. |
| due_date | date | Payment due date. |
Request
curl -X POST https://cotlet.dev/api/v1/yardbook/create_invoice \
-H "Authorization: Bearer $COTLET_API_KEY" \
-H "Content-Type: application/json" \
-d '{"customer_id":"customer_8c41d2"}' result = client.call("yardbook", "create_invoice", {"customer_id":"customer_8c41d2"}) const result = await cotlet.call('yardbook', 'create_invoice', {"customer_id":"customer_8c41d2"}); cotlet call yardbook create_invoice --data '{"customer_id":"customer_8c41d2"}' Example response
{
"invoice_id": "73210",
"customer_id": "284117",
"job_id": "9930412",
"status": "unpaid",
"sent": false,
"total": "85.00",
"amount_due": "85.00",
"due_date": "2026-10-27"
} POST https://cotlet.dev/api/v1/yardbook/send_invoice
Emails an invoice to the customer, with your optional note, for example a reminder on an overdue one. The customer needs an email address on file. By default you confirm each call; you can switch that off for this tool.
Parameters
| Name | Type | Description |
|---|---|---|
| invoice_id required | string | Invoice ID from list_invoices. |
| message | string | Note added to the email, e.g. a reminder. |
Request
curl -X POST https://cotlet.dev/api/v1/yardbook/send_invoice \
-H "Authorization: Bearer $COTLET_API_KEY" \
-H "Content-Type: application/json" \
-d '{"invoice_id":"invoice_8c41d2"}' result = client.call("yardbook", "send_invoice", {"invoice_id":"invoice_8c41d2"}) const result = await cotlet.call('yardbook', 'send_invoice', {"invoice_id":"invoice_8c41d2"}); cotlet call yardbook send_invoice --data '{"invoice_id":"invoice_8c41d2"}' Example response
{
"invoice_id": "73194",
"status": "unpaid",
"sent_to": "office@parker.example.com"
} POST https://cotlet.dev/api/v1/yardbook/record_payment
Records a payment you received against one invoice. The amount due goes down by the amount; an invoice paid in full becomes paid. It moves no money and charges no card. By default you confirm each call; you can switch that off for this tool.
Parameters
| Name | Type | Description |
|---|---|---|
| invoice_id required | string | Invoice ID from list_invoices. |
| amount required | string | Amount received, e.g. 240.00. |
| method required | string | How it was paid, e.g. Check or Cash. |
| date | date | Date received. Default: today. |
| reference | string | Check number or note. |
Request
curl -X POST https://cotlet.dev/api/v1/yardbook/record_payment \
-H "Authorization: Bearer $COTLET_API_KEY" \
-H "Content-Type: application/json" \
-d '{"invoice_id":"73194","amount":"240.00","method":"Check","date":"2026-10-16","reference":"Check 3318"}' result = client.call("yardbook", "record_payment", {"invoice_id":"73194","amount":"240.00","method":"Check","date":"2026-10-16","reference":"Check 3318"}) const result = await cotlet.call('yardbook', 'record_payment', {"invoice_id":"73194","amount":"240.00","method":"Check","date":"2026-10-16","reference":"Check 3318"}); cotlet call yardbook record_payment --data '{"invoice_id":"73194","amount":"240.00","method":"Check","date":"2026-10-16","reference":"Check 3318"}' Example response
{
"invoice_id": "73194",
"payment": {
"amount": "240.00",
"method": "Check",
"date": "2026-10-11",
"reference": "Check 3318"
},
"amount_due": "0.00",
"status": "paid"
}