{"openapi":"3.1.0","info":{"title":"TradesWork API","version":"2026-10-14","description":"REST API for integrations: customers, locations, jobs, dispatch, estimates, invoices, payments, price book and technicians.\n\nAuthenticate with a company API key (`Authorization: Bearer tos_…`, Settings › Integrations › API Application Access) or an OAuth access token.\n\nMoney is integer cents; times are ISO-8601. Lists are newest first with cursor pagination (`limit`, `cursor`, `nextCursor`).\n\nRate limit: 120 requests per minute per credential (`X-RateLimit-*` headers; 429 with `Retry-After`).\n\nWebhooks are signed: `tradesos-signature: t=<unix>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">` with the endpoint secret."},"servers":[{"url":"https://tradesos-three.vercel.app/api/v1/platform"}],"tags":[{"name":"Account"},{"name":"Customers"},{"name":"Locations"},{"name":"Jobs"},{"name":"Appointments"},{"name":"Dispatch"},{"name":"Estimates"},{"name":"Invoices"},{"name":"Payments"},{"name":"Price book"},{"name":"Technicians"},{"name":"Webhooks"}],"paths":{"/me":{"get":{"operationId":"getMe","tags":["Account"],"summary":"The company and access behind this credential","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Me"}}}},"400":{"description":"Invalid request (code: invalid)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid credential","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden or insufficient_scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (also: belongs to another company)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A business rule said no (rejected) or idempotency_key_reused","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited: see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/customers":{"get":{"operationId":"listCustomers","tags":["Customers"],"summary":"List customers","security":[{"bearer":["customers:read"]},{"oauth2":["customers:read"]}],"parameters":[{"name":"limit","in":"query","required":false,"description":"Page size, 1–100 (default 25).","schema":{"default":25,"description":"Page size, 1–100 (default 25).","type":"integer","minimum":1,"maximum":100}},{"name":"cursor","in":"query","required":false,"description":"nextCursor from the previous page.","schema":{"description":"nextCursor from the previous page.","type":"string","maxLength":200}},{"name":"updatedSince","in":"query","required":false,"description":"Only records changed at or after this time (sync).","schema":{"description":"Only records changed at or after this time (sync).","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},{"name":"createdSince","in":"query","required":false,"description":"Only records created at or after this time.","schema":{"description":"Only records created at or after this time.","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},{"name":"externalSource","in":"query","required":false,"description":"Imported records: the source system (servicetitan, housecallpro, jobber, fieldedge…).","schema":{"description":"Imported records: the source system (servicetitan, housecallpro, jobber, fieldedge…).","type":"string","maxLength":60}},{"name":"externalId","in":"query","required":false,"description":"Imported records: the id in the source system (use with externalSource).","schema":{"description":"Imported records: the id in the source system (use with externalSource).","type":"string","maxLength":120}},{"name":"q","in":"query","required":false,"description":"Name contains.","schema":{"description":"Name contains.","type":"string","maxLength":80}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerPage"}}}},"400":{"description":"Invalid request (code: invalid)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid credential","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden or insufficient_scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (also: belongs to another company)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A business rule said no (rejected) or idempotency_key_reused","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited: see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"createCustomer","tags":["Customers"],"summary":"Create a customer (optionally with a first location)","security":[{"bearer":["customers:write"]},{"oauth2":["customers:write"]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Up to 200 characters. A retry with the same key and body returns the first response; reusing it with a different body is a 422.","schema":{"type":"string","maxLength":200}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"type":{"default":"residential","type":"string","enum":["residential","commercial"]},"name":{"type":"string","minLength":2,"maxLength":120},"email":{"anyOf":[{"type":"string","const":""},{"type":"string","maxLength":200,"format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"}]},"phone":{"type":"string","maxLength":30,"pattern":"^[0-9()+.\\-\\s]*$"},"notes":{"type":"string","maxLength":2000},"location":{"type":"object","properties":{"name":{"type":"string","maxLength":80},"street":{"type":"string","minLength":3,"maxLength":160},"city":{"type":"string","maxLength":80},"state":{"type":"string","maxLength":40},"zip":{"type":"string","maxLength":12,"pattern":"^[A-Za-z0-9 -]*$"},"accessNotes":{"type":"string","maxLength":1000}},"required":["street"]}},"required":["name"]}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Customer"}}}},"400":{"description":"Invalid request (code: invalid)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid credential","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden or insufficient_scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (also: belongs to another company)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A business rule said no (rejected) or idempotency_key_reused","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited: see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/customers/{id}":{"get":{"operationId":"getCustomer","tags":["Customers"],"summary":"Get a customer","security":[{"bearer":["customers:read"]},{"oauth2":["customers:read"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Customer"}}}},"400":{"description":"Invalid request (code: invalid)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid credential","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden or insufficient_scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (also: belongs to another company)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A business rule said no (rejected) or idempotency_key_reused","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited: see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/locations":{"get":{"operationId":"listLocations","tags":["Locations"],"summary":"List service locations","security":[{"bearer":["customers:read"]},{"oauth2":["customers:read"]}],"parameters":[{"name":"limit","in":"query","required":false,"description":"Page size, 1–100 (default 25).","schema":{"default":25,"description":"Page size, 1–100 (default 25).","type":"integer","minimum":1,"maximum":100}},{"name":"cursor","in":"query","required":false,"description":"nextCursor from the previous page.","schema":{"description":"nextCursor from the previous page.","type":"string","maxLength":200}},{"name":"updatedSince","in":"query","required":false,"description":"Only records changed at or after this time (sync).","schema":{"description":"Only records changed at or after this time (sync).","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},{"name":"createdSince","in":"query","required":false,"description":"Only records created at or after this time.","schema":{"description":"Only records created at or after this time.","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},{"name":"externalSource","in":"query","required":false,"description":"Imported records: the source system (servicetitan, housecallpro, jobber, fieldedge…).","schema":{"description":"Imported records: the source system (servicetitan, housecallpro, jobber, fieldedge…).","type":"string","maxLength":60}},{"name":"externalId","in":"query","required":false,"description":"Imported records: the id in the source system (use with externalSource).","schema":{"description":"Imported records: the id in the source system (use with externalSource).","type":"string","maxLength":120}},{"name":"customerId","in":"query","required":false,"schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LocationPage"}}}},"400":{"description":"Invalid request (code: invalid)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid credential","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden or insufficient_scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (also: belongs to another company)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A business rule said no (rejected) or idempotency_key_reused","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited: see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/locations/{id}":{"get":{"operationId":"getLocation","tags":["Locations"],"summary":"Get a location","security":[{"bearer":["customers:read"]},{"oauth2":["customers:read"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Location"}}}},"400":{"description":"Invalid request (code: invalid)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid credential","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden or insufficient_scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (also: belongs to another company)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A business rule said no (rejected) or idempotency_key_reused","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited: see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/customers/{id}/locations":{"post":{"operationId":"createLocation","tags":["Locations"],"summary":"Add a service location to a customer","security":[{"bearer":["customers:write"]},{"oauth2":["customers:write"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Up to 200 characters. A retry with the same key and body returns the first response; reusing it with a different body is a 422.","schema":{"type":"string","maxLength":200}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","maxLength":80},"street":{"type":"string","minLength":3,"maxLength":160},"city":{"type":"string","maxLength":80},"state":{"type":"string","maxLength":40},"zip":{"type":"string","maxLength":12,"pattern":"^[A-Za-z0-9 -]*$"},"accessNotes":{"type":"string","maxLength":1000}},"required":["street"]}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Location"}}}},"400":{"description":"Invalid request (code: invalid)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid credential","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden or insufficient_scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (also: belongs to another company)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A business rule said no (rejected) or idempotency_key_reused","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited: see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/jobs":{"get":{"operationId":"listJobs","tags":["Jobs"],"summary":"List jobs","security":[{"bearer":["jobs:read"]},{"oauth2":["jobs:read"]}],"parameters":[{"name":"limit","in":"query","required":false,"description":"Page size, 1–100 (default 25).","schema":{"default":25,"description":"Page size, 1–100 (default 25).","type":"integer","minimum":1,"maximum":100}},{"name":"cursor","in":"query","required":false,"description":"nextCursor from the previous page.","schema":{"description":"nextCursor from the previous page.","type":"string","maxLength":200}},{"name":"updatedSince","in":"query","required":false,"description":"Only records changed at or after this time (sync).","schema":{"description":"Only records changed at or after this time (sync).","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},{"name":"createdSince","in":"query","required":false,"description":"Only records created at or after this time.","schema":{"description":"Only records created at or after this time.","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},{"name":"externalSource","in":"query","required":false,"description":"Imported records: the source system (servicetitan, housecallpro, jobber, fieldedge…).","schema":{"description":"Imported records: the source system (servicetitan, housecallpro, jobber, fieldedge…).","type":"string","maxLength":60}},{"name":"externalId","in":"query","required":false,"description":"Imported records: the id in the source system (use with externalSource).","schema":{"description":"Imported records: the id in the source system (use with externalSource).","type":"string","maxLength":120}},{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["unscheduled","scheduled","in_progress","follow_up","completed","canceled"]}},{"name":"customerId","in":"query","required":false,"schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"externalRef","in":"query","required":false,"schema":{"type":"string","maxLength":120}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobPage"}}}},"400":{"description":"Invalid request (code: invalid)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid credential","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden or insufficient_scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (also: belongs to another company)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A business rule said no (rejected) or idempotency_key_reused","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited: see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"createJob","tags":["Jobs"],"summary":"Book a job for an existing customer and location","description":"Lands unscheduled for the dispatcher. Idempotent on externalRef and on the Idempotency-Key header.","security":[{"bearer":["jobs:write"]},{"oauth2":["jobs:write"]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Up to 200 characters. A retry with the same key and body returns the first response; reusing it with a different body is a 422.","schema":{"type":"string","maxLength":200}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"customerId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"locationId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"jobTypeId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"businessUnitId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"campaignId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"summary":{"type":"string","minLength":3,"maxLength":120},"description":{"type":"string","maxLength":4000},"priority":{"default":"normal","type":"string","enum":["normal","high","emergency"]},"externalRef":{"description":"Your id for this job; booking the same externalRef twice returns the existing job.","type":"string","minLength":1,"maxLength":120}},"required":["customerId","locationId","summary"]}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Job"}}}},"400":{"description":"Invalid request (code: invalid)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid credential","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden or insufficient_scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (also: belongs to another company)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A business rule said no (rejected) or idempotency_key_reused","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited: see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/jobs/{id}":{"get":{"operationId":"getJob","tags":["Jobs"],"summary":"Get a job","security":[{"bearer":["jobs:read"]},{"oauth2":["jobs:read"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Job"}}}},"400":{"description":"Invalid request (code: invalid)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid credential","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden or insufficient_scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (also: belongs to another company)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A business rule said no (rejected) or idempotency_key_reused","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited: see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/appointments":{"get":{"operationId":"listAppointments","tags":["Appointments"],"summary":"List appointments","security":[{"bearer":["jobs:read"]},{"oauth2":["jobs:read"]}],"parameters":[{"name":"limit","in":"query","required":false,"description":"Page size, 1–100 (default 25).","schema":{"default":25,"description":"Page size, 1–100 (default 25).","type":"integer","minimum":1,"maximum":100}},{"name":"cursor","in":"query","required":false,"description":"nextCursor from the previous page.","schema":{"description":"nextCursor from the previous page.","type":"string","maxLength":200}},{"name":"updatedSince","in":"query","required":false,"description":"Only records changed at or after this time (sync).","schema":{"description":"Only records changed at or after this time (sync).","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},{"name":"createdSince","in":"query","required":false,"description":"Only records created at or after this time.","schema":{"description":"Only records created at or after this time.","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},{"name":"externalSource","in":"query","required":false,"description":"Imported records: the source system (servicetitan, housecallpro, jobber, fieldedge…).","schema":{"description":"Imported records: the source system (servicetitan, housecallpro, jobber, fieldedge…).","type":"string","maxLength":60}},{"name":"externalId","in":"query","required":false,"description":"Imported records: the id in the source system (use with externalSource).","schema":{"description":"Imported records: the id in the source system (use with externalSource).","type":"string","maxLength":120}},{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["scheduled","dispatched","en_route","working","done","canceled"]}},{"name":"jobId","in":"query","required":false,"schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"technicianId","in":"query","required":false,"schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"startsAfter","in":"query","required":false,"description":"Arrival window starts at or after.","schema":{"description":"Arrival window starts at or after.","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},{"name":"startsBefore","in":"query","required":false,"description":"Arrival window starts before.","schema":{"description":"Arrival window starts before.","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppointmentPage"}}}},"400":{"description":"Invalid request (code: invalid)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid credential","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden or insufficient_scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (also: belongs to another company)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A business rule said no (rejected) or idempotency_key_reused","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited: see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"scheduleAppointment","tags":["Dispatch"],"summary":"Schedule an appointment on a job (arrival window, technicians)","security":[{"bearer":["dispatch:write"]},{"oauth2":["dispatch:write"]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Up to 200 characters. A retry with the same key and body returns the first response; reusing it with a different body is a 422.","schema":{"type":"string","maxLength":200}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"jobId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"arrivalStart":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"arrivalEnd":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"durationMinutes":{"default":60,"type":"integer","minimum":15,"maximum":1440},"technicianIds":{"default":[],"maxItems":10,"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"instructions":{"type":"string","maxLength":1000}},"required":["jobId","arrivalStart","arrivalEnd"]}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Appointment"}}}},"400":{"description":"Invalid request (code: invalid)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid credential","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden or insufficient_scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (also: belongs to another company)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A business rule said no (rejected) or idempotency_key_reused","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited: see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/appointments/{id}":{"get":{"operationId":"getAppointment","tags":["Appointments"],"summary":"Get an appointment","security":[{"bearer":["jobs:read"]},{"oauth2":["jobs:read"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Appointment"}}}},"400":{"description":"Invalid request (code: invalid)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid credential","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden or insufficient_scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (also: belongs to another company)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A business rule said no (rejected) or idempotency_key_reused","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited: see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/appointments/{id}/assign":{"post":{"operationId":"assignAppointment","tags":["Dispatch"],"summary":"Assign technicians (replaces the crew)","security":[{"bearer":["dispatch:write"]},{"oauth2":["dispatch:write"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"technicianIds":{"maxItems":10,"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}},"required":["technicianIds"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Appointment"}}}},"400":{"description":"Invalid request (code: invalid)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid credential","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden or insufficient_scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (also: belongs to another company)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A business rule said no (rejected) or idempotency_key_reused","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited: see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/appointments/{id}/status":{"post":{"operationId":"transitionAppointment","tags":["Dispatch"],"summary":"Move an appointment: dispatched, en_route, working (arrived), done, canceled","description":"Repeating the current status is a no-op. Completing needs an outcome and summary, and the company's required forms and photos.","security":[{"bearer":["dispatch:write"]},{"oauth2":["dispatch:write"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"to":{"type":"string","enum":["scheduled","dispatched","en_route","working","done","canceled"]},"outcome":{"type":"string","enum":["job_complete","follow_up"]},"summary":{"type":"string","maxLength":4000}},"required":["to"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Appointment"}}}},"400":{"description":"Invalid request (code: invalid)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid credential","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden or insufficient_scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (also: belongs to another company)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A business rule said no (rejected) or idempotency_key_reused","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited: see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/estimates":{"get":{"operationId":"listEstimates","tags":["Estimates"],"summary":"List estimates (one per option)","security":[{"bearer":["estimates:read"]},{"oauth2":["estimates:read"]}],"parameters":[{"name":"limit","in":"query","required":false,"description":"Page size, 1–100 (default 25).","schema":{"default":25,"description":"Page size, 1–100 (default 25).","type":"integer","minimum":1,"maximum":100}},{"name":"cursor","in":"query","required":false,"description":"nextCursor from the previous page.","schema":{"description":"nextCursor from the previous page.","type":"string","maxLength":200}},{"name":"updatedSince","in":"query","required":false,"description":"Only records changed at or after this time (sync).","schema":{"description":"Only records changed at or after this time (sync).","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},{"name":"createdSince","in":"query","required":false,"description":"Only records created at or after this time.","schema":{"description":"Only records created at or after this time.","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},{"name":"externalSource","in":"query","required":false,"description":"Imported records: the source system (servicetitan, housecallpro, jobber, fieldedge…).","schema":{"description":"Imported records: the source system (servicetitan, housecallpro, jobber, fieldedge…).","type":"string","maxLength":60}},{"name":"externalId","in":"query","required":false,"description":"Imported records: the id in the source system (use with externalSource).","schema":{"description":"Imported records: the id in the source system (use with externalSource).","type":"string","maxLength":120}},{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["open","sold","dismissed"]}},{"name":"jobId","in":"query","required":false,"schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EstimatePage"}}}},"400":{"description":"Invalid request (code: invalid)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid credential","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden or insufficient_scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (also: belongs to another company)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A business rule said no (rejected) or idempotency_key_reused","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited: see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/estimates/{id}":{"get":{"operationId":"getEstimate","tags":["Estimates"],"summary":"Get an estimate","security":[{"bearer":["estimates:read"]},{"oauth2":["estimates:read"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Estimate"}}}},"400":{"description":"Invalid request (code: invalid)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid credential","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden or insufficient_scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (also: belongs to another company)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A business rule said no (rejected) or idempotency_key_reused","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited: see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/invoices":{"get":{"operationId":"listInvoices","tags":["Invoices"],"summary":"List invoices","security":[{"bearer":["invoices:read"]},{"oauth2":["invoices:read"]}],"parameters":[{"name":"limit","in":"query","required":false,"description":"Page size, 1–100 (default 25).","schema":{"default":25,"description":"Page size, 1–100 (default 25).","type":"integer","minimum":1,"maximum":100}},{"name":"cursor","in":"query","required":false,"description":"nextCursor from the previous page.","schema":{"description":"nextCursor from the previous page.","type":"string","maxLength":200}},{"name":"updatedSince","in":"query","required":false,"description":"Only records changed at or after this time (sync).","schema":{"description":"Only records changed at or after this time (sync).","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},{"name":"createdSince","in":"query","required":false,"description":"Only records created at or after this time.","schema":{"description":"Only records created at or after this time.","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},{"name":"externalSource","in":"query","required":false,"description":"Imported records: the source system (servicetitan, housecallpro, jobber, fieldedge…).","schema":{"description":"Imported records: the source system (servicetitan, housecallpro, jobber, fieldedge…).","type":"string","maxLength":60}},{"name":"externalId","in":"query","required":false,"description":"Imported records: the id in the source system (use with externalSource).","schema":{"description":"Imported records: the id in the source system (use with externalSource).","type":"string","maxLength":120}},{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["draft","sent","paid","void"]}},{"name":"jobId","in":"query","required":false,"schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvoicePage"}}}},"400":{"description":"Invalid request (code: invalid)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid credential","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden or insufficient_scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (also: belongs to another company)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A business rule said no (rejected) or idempotency_key_reused","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited: see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/invoices/{id}":{"get":{"operationId":"getInvoice","tags":["Invoices"],"summary":"Get an invoice","security":[{"bearer":["invoices:read"]},{"oauth2":["invoices:read"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Invoice"}}}},"400":{"description":"Invalid request (code: invalid)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid credential","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden or insufficient_scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (also: belongs to another company)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A business rule said no (rejected) or idempotency_key_reused","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited: see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/invoices/{id}/payments":{"post":{"operationId":"recordPayment","tags":["Payments"],"summary":"Record a cash, check or other payment","description":"Paid status follows payments. Use the Idempotency-Key header so a retry records the payment once.","security":[{"bearer":["payments:write"]},{"oauth2":["payments:write"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Up to 200 characters. A retry with the same key and body returns the first response; reusing it with a different body is a 422.","schema":{"type":"string","maxLength":200}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"amount":{"type":"integer","minimum":1,"maximum":100000000,"description":"Integer cents"},"method":{"type":"string","enum":["cash","check","other"]},"reference":{"type":"string","maxLength":80},"memo":{"type":"string","maxLength":500}},"required":["amount","method"]}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Invoice"}}}},"400":{"description":"Invalid request (code: invalid)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid credential","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden or insufficient_scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (also: belongs to another company)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A business rule said no (rejected) or idempotency_key_reused","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited: see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/invoices/{id}/checkout":{"post":{"operationId":"createCheckout","tags":["Payments"],"summary":"Create a card payment link for the balance","description":"409 processor_unavailable when no card processor is connected (never a fake link).","security":[{"bearer":["payments:write"]},{"oauth2":["payments:write"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Up to 200 characters. A retry with the same key and body returns the first response; reusing it with a different body is a 422.","schema":{"type":"string","maxLength":200}}],"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckoutLink"}}}},"400":{"description":"Invalid request (code: invalid)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid credential","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden or insufficient_scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (also: belongs to another company)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A business rule said no (rejected) or idempotency_key_reused","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited: see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/payments":{"get":{"operationId":"listPayments","tags":["Payments"],"summary":"List payments","security":[{"bearer":["invoices:read"]},{"oauth2":["invoices:read"]}],"parameters":[{"name":"limit","in":"query","required":false,"description":"Page size, 1–100 (default 25).","schema":{"default":25,"description":"Page size, 1–100 (default 25).","type":"integer","minimum":1,"maximum":100}},{"name":"cursor","in":"query","required":false,"description":"nextCursor from the previous page.","schema":{"description":"nextCursor from the previous page.","type":"string","maxLength":200}},{"name":"updatedSince","in":"query","required":false,"description":"Only records changed at or after this time (sync).","schema":{"description":"Only records changed at or after this time (sync).","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},{"name":"createdSince","in":"query","required":false,"description":"Only records created at or after this time.","schema":{"description":"Only records created at or after this time.","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},{"name":"externalSource","in":"query","required":false,"description":"Imported records: the source system (servicetitan, housecallpro, jobber, fieldedge…).","schema":{"description":"Imported records: the source system (servicetitan, housecallpro, jobber, fieldedge…).","type":"string","maxLength":60}},{"name":"externalId","in":"query","required":false,"description":"Imported records: the id in the source system (use with externalSource).","schema":{"description":"Imported records: the id in the source system (use with externalSource).","type":"string","maxLength":120}},{"name":"invoiceId","in":"query","required":false,"schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["pending","succeeded","failed","refunded"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentPage"}}}},"400":{"description":"Invalid request (code: invalid)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid credential","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden or insufficient_scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (also: belongs to another company)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A business rule said no (rejected) or idempotency_key_reused","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited: see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/payments/{id}":{"get":{"operationId":"getPayment","tags":["Payments"],"summary":"Get a payment","security":[{"bearer":["invoices:read"]},{"oauth2":["invoices:read"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Payment"}}}},"400":{"description":"Invalid request (code: invalid)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid credential","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden or insufficient_scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (also: belongs to another company)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A business rule said no (rejected) or idempotency_key_reused","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited: see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/pricebook/items":{"get":{"operationId":"listPricebookItems","tags":["Price book"],"summary":"List price book items","security":[{"bearer":["pricebook:read"]},{"oauth2":["pricebook:read"]}],"parameters":[{"name":"limit","in":"query","required":false,"description":"Page size, 1–100 (default 25).","schema":{"default":25,"description":"Page size, 1–100 (default 25).","type":"integer","minimum":1,"maximum":100}},{"name":"cursor","in":"query","required":false,"description":"nextCursor from the previous page.","schema":{"description":"nextCursor from the previous page.","type":"string","maxLength":200}},{"name":"updatedSince","in":"query","required":false,"description":"Only records changed at or after this time (sync).","schema":{"description":"Only records changed at or after this time (sync).","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},{"name":"createdSince","in":"query","required":false,"description":"Only records created at or after this time.","schema":{"description":"Only records created at or after this time.","type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}},{"name":"externalSource","in":"query","required":false,"description":"Imported records: the source system (servicetitan, housecallpro, jobber, fieldedge…).","schema":{"description":"Imported records: the source system (servicetitan, housecallpro, jobber, fieldedge…).","type":"string","maxLength":60}},{"name":"externalId","in":"query","required":false,"description":"Imported records: the id in the source system (use with externalSource).","schema":{"description":"Imported records: the id in the source system (use with externalSource).","type":"string","maxLength":120}},{"name":"kind","in":"query","required":false,"schema":{"type":"string","enum":["service","material","equipment"]}},{"name":"active","in":"query","required":false,"schema":{"type":"string","enum":["true","false"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PricebookItemPage"}}}},"400":{"description":"Invalid request (code: invalid)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid credential","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden or insufficient_scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (also: belongs to another company)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A business rule said no (rejected) or idempotency_key_reused","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited: see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/pricebook/items/{id}":{"get":{"operationId":"getPricebookItem","tags":["Price book"],"summary":"Get a price book item","security":[{"bearer":["pricebook:read"]},{"oauth2":["pricebook:read"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PricebookItem"}}}},"400":{"description":"Invalid request (code: invalid)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid credential","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden or insufficient_scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (also: belongs to another company)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A business rule said no (rejected) or idempotency_key_reused","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited: see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/technicians":{"get":{"operationId":"listTechnicians","tags":["Technicians"],"summary":"People who can be assigned to appointments","security":[{"bearer":["technicians:read"]},{"oauth2":["technicians:read"]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TechnicianList"}}}},"400":{"description":"Invalid request (code: invalid)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid credential","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden or insufficient_scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (also: belongs to another company)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A business rule said no (rejected) or idempotency_key_reused","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited: see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/webhooks/event-types":{"get":{"operationId":"listWebhookEventTypes","tags":["Webhooks"],"summary":"Every event type a webhook can receive","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EventTypeList"}}}},"400":{"description":"Invalid request (code: invalid)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid credential","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden or insufficient_scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (also: belongs to another company)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A business rule said no (rejected) or idempotency_key_reused","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited: see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/webhooks":{"get":{"operationId":"listWebhooks","tags":["Webhooks"],"summary":"Webhook endpoints this credential created","security":[{"bearer":["webhooks:manage"]},{"oauth2":["webhooks:manage"]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpointList"}}}},"400":{"description":"Invalid request (code: invalid)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid credential","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden or insufficient_scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (also: belongs to another company)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A business rule said no (rejected) or idempotency_key_reused","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited: see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"createWebhook","tags":["Webhooks"],"summary":"Subscribe (REST hook: Zapier, n8n, Make)","description":"Returns the signing secret once. Event types are limited to what this credential may read.","security":[{"bearer":["webhooks:manage"]},{"oauth2":["webhooks:manage"]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Up to 200 characters. A retry with the same key and body returns the first response; reusing it with a different body is a 422.","schema":{"type":"string","maxLength":200}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","maxLength":2000,"format":"uri"},"description":{"type":"string","maxLength":200},"eventTypes":{"minItems":1,"maxItems":27,"type":"array","items":{"anyOf":[{"type":"string","enum":["customer.created","location.created","job.created","job.completed","job.canceled","appointment.scheduled","appointment.rescheduled","appointment.assigned","appointment.status_changed","estimate.created","estimate.sold","estimate.dismissed","invoice.created","invoice.sent","payment.recorded","payment.succeeded","payment.failed","payment.refunded","membership.sold","membership.renewed","membership.canceled","membership.expired","lead.received","lead.converted","pricebook_item.created","pricebook_item.updated"]},{"type":"string","const":"*"}]}}},"required":["url","eventTypes"]}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpointCreated"}}}},"400":{"description":"Invalid request (code: invalid)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid credential","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden or insufficient_scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (also: belongs to another company)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A business rule said no (rejected) or idempotency_key_reused","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited: see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/webhooks/{id}":{"delete":{"operationId":"deleteWebhook","tags":["Webhooks"],"summary":"Unsubscribe","security":[{"bearer":["webhooks:manage"]},{"oauth2":["webhooks:manage"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Deleted"}}}},"400":{"description":"Invalid request (code: invalid)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid credential","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden or insufficient_scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (also: belongs to another company)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A business rule said no (rejected) or idempotency_key_reused","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited: see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/webhooks/{id}/test":{"post":{"operationId":"testWebhook","tags":["Webhooks"],"summary":"Send a signed ping event now","security":[{"bearer":["webhooks:manage"]},{"oauth2":["webhooks:manage"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestDelivery"}}}},"400":{"description":"Invalid request (code: invalid)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid credential","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden or insufficient_scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found (also: belongs to another company)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A business rule said no (rejected) or idempotency_key_reused","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited: see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"webhooks":{"customer.created":{"post":{"summary":"Customer created","description":"Signed with the tradesos-signature header. data.object is a customer.","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"200":{"description":"Any 2xx acknowledges. Anything else (or no answer within 10 s) is retried with backoff."}}}},"location.created":{"post":{"summary":"Service location added","description":"Signed with the tradesos-signature header. data.object is a location.","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"200":{"description":"Any 2xx acknowledges. Anything else (or no answer within 10 s) is retried with backoff."}}}},"job.created":{"post":{"summary":"Job booked","description":"Signed with the tradesos-signature header. data.object is a job.","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"200":{"description":"Any 2xx acknowledges. Anything else (or no answer within 10 s) is retried with backoff."}}}},"job.completed":{"post":{"summary":"Job completed","description":"Signed with the tradesos-signature header. data.object is a job.","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"200":{"description":"Any 2xx acknowledges. Anything else (or no answer within 10 s) is retried with backoff."}}}},"job.canceled":{"post":{"summary":"Job canceled","description":"Signed with the tradesos-signature header. data.object is a job.","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"200":{"description":"Any 2xx acknowledges. Anything else (or no answer within 10 s) is retried with backoff."}}}},"appointment.scheduled":{"post":{"summary":"Appointment scheduled","description":"Signed with the tradesos-signature header. data.object is a appointment.","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"200":{"description":"Any 2xx acknowledges. Anything else (or no answer within 10 s) is retried with backoff."}}}},"appointment.rescheduled":{"post":{"summary":"Appointment rescheduled","description":"Signed with the tradesos-signature header. data.object is a appointment.","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"200":{"description":"Any 2xx acknowledges. Anything else (or no answer within 10 s) is retried with backoff."}}}},"appointment.assigned":{"post":{"summary":"Technicians assigned (dispatch)","description":"Signed with the tradesos-signature header. data.object is a appointment.","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"200":{"description":"Any 2xx acknowledges. Anything else (or no answer within 10 s) is retried with backoff."}}}},"appointment.status_changed":{"post":{"summary":"Appointment status changed (dispatched, en route, arrived, done, canceled)","description":"Signed with the tradesos-signature header. data.object is a appointment.","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"200":{"description":"Any 2xx acknowledges. Anything else (or no answer within 10 s) is retried with backoff."}}}},"estimate.created":{"post":{"summary":"Estimate created","description":"Signed with the tradesos-signature header. data.object is a estimate.","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"200":{"description":"Any 2xx acknowledges. Anything else (or no answer within 10 s) is retried with backoff."}}}},"estimate.sold":{"post":{"summary":"Estimate sold","description":"Signed with the tradesos-signature header. data.object is a estimate.","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"200":{"description":"Any 2xx acknowledges. Anything else (or no answer within 10 s) is retried with backoff."}}}},"estimate.dismissed":{"post":{"summary":"Estimate dismissed","description":"Signed with the tradesos-signature header. data.object is a estimate.","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"200":{"description":"Any 2xx acknowledges. Anything else (or no answer within 10 s) is retried with backoff."}}}},"invoice.created":{"post":{"summary":"Invoice created","description":"Signed with the tradesos-signature header. data.object is a invoice.","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"200":{"description":"Any 2xx acknowledges. Anything else (or no answer within 10 s) is retried with backoff."}}}},"invoice.sent":{"post":{"summary":"Invoice sent","description":"Signed with the tradesos-signature header. data.object is a invoice.","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"200":{"description":"Any 2xx acknowledges. Anything else (or no answer within 10 s) is retried with backoff."}}}},"payment.recorded":{"post":{"summary":"Payment recorded (cash, check, other)","description":"Signed with the tradesos-signature header. data.object is a payment.","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"200":{"description":"Any 2xx acknowledges. Anything else (or no answer within 10 s) is retried with backoff."}}}},"payment.succeeded":{"post":{"summary":"Card or ACH payment succeeded","description":"Signed with the tradesos-signature header. data.object is a payment.","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"200":{"description":"Any 2xx acknowledges. Anything else (or no answer within 10 s) is retried with backoff."}}}},"payment.failed":{"post":{"summary":"Card or ACH payment failed","description":"Signed with the tradesos-signature header. data.object is a payment.","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"200":{"description":"Any 2xx acknowledges. Anything else (or no answer within 10 s) is retried with backoff."}}}},"payment.refunded":{"post":{"summary":"Refund issued","description":"Signed with the tradesos-signature header. data.object is a invoice.","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"200":{"description":"Any 2xx acknowledges. Anything else (or no answer within 10 s) is retried with backoff."}}}},"membership.sold":{"post":{"summary":"Membership sold","description":"Signed with the tradesos-signature header. data.object is a membership.","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"200":{"description":"Any 2xx acknowledges. Anything else (or no answer within 10 s) is retried with backoff."}}}},"membership.renewed":{"post":{"summary":"Membership renewed","description":"Signed with the tradesos-signature header. data.object is a membership.","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"200":{"description":"Any 2xx acknowledges. Anything else (or no answer within 10 s) is retried with backoff."}}}},"membership.canceled":{"post":{"summary":"Membership canceled","description":"Signed with the tradesos-signature header. data.object is a membership.","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"200":{"description":"Any 2xx acknowledges. Anything else (or no answer within 10 s) is retried with backoff."}}}},"membership.expired":{"post":{"summary":"Membership expired","description":"Signed with the tradesos-signature header. data.object is a membership.","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"200":{"description":"Any 2xx acknowledges. Anything else (or no answer within 10 s) is retried with backoff."}}}},"lead.received":{"post":{"summary":"Lead received","description":"Signed with the tradesos-signature header. data.object is a lead.","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"200":{"description":"Any 2xx acknowledges. Anything else (or no answer within 10 s) is retried with backoff."}}}},"lead.converted":{"post":{"summary":"Lead converted to a job","description":"Signed with the tradesos-signature header. data.object is a lead.","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"200":{"description":"Any 2xx acknowledges. Anything else (or no answer within 10 s) is retried with backoff."}}}},"pricebook_item.created":{"post":{"summary":"Price book item created","description":"Signed with the tradesos-signature header. data.object is a pricebook_item.","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"200":{"description":"Any 2xx acknowledges. Anything else (or no answer within 10 s) is retried with backoff."}}}},"pricebook_item.updated":{"post":{"summary":"Price book item updated","description":"Signed with the tradesos-signature header. data.object is a pricebook_item.","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"200":{"description":"Any 2xx acknowledges. Anything else (or no answer within 10 s) is retried with backoff."}}}}},"components":{"schemas":{"Error":{"type":"object","properties":{"error":{"type":"string","description":"Plain-words message, safe to show to a person."},"code":{"type":"string","enum":["unauthenticated","forbidden","insufficient_scope","not_found","invalid","rejected","rate_limited","idempotency_key_reused","idempotency_in_progress","processor_unavailable","method_not_allowed","server_error"]},"issues":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"],"additionalProperties":false}},"requestId":{"type":"string"}},"required":["error","code"],"additionalProperties":false},"WebhookEvent":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$","description":"Event id. Deliveries can repeat: use it to process each event once."},"type":{"type":"string"},"apiVersion":{"type":"string"},"createdAt":{"type":"string","description":"When the change happened."},"company":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"required":["id"],"additionalProperties":false},"data":{"type":"object","properties":{"objectType":{"type":"string"},"objectId":{"type":["string","null"]},"object":{"anyOf":[{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},{"type":"null"}],"description":"The resource as the REST API returns it, at delivery-preparation time (null if it no longer exists)."},"change":{"anyOf":[{"type":"object","properties":{"before":{},"after":{}},"required":["before","after"],"additionalProperties":false},{"type":"null"}],"description":"What changed (no contact details)."}},"required":["objectType","objectId","object","change"],"additionalProperties":false}},"required":["id","type","apiVersion","createdAt","company","data"],"additionalProperties":false},"Me":{"type":"object","properties":{"company":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"},"timezone":{"type":"string"}},"required":["id","name","timezone"],"additionalProperties":false},"connection":{"type":"object","properties":{"kind":{"type":"string","enum":["api_key","oauth"]},"name":{"type":"string"}},"required":["kind","name"],"additionalProperties":false},"scopes":{"type":"array","items":{"type":"string"}},"apiVersion":{"type":"string"}},"required":["company","connection","scopes","apiVersion"],"additionalProperties":false},"CustomerPage":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/$defs/Customer"}},"hasMore":{"type":"boolean"},"nextCursor":{"type":["string","null"]}},"required":["data","hasMore","nextCursor"],"additionalProperties":false},"Customer":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"type":{"type":"string","enum":["residential","commercial"]},"name":{"type":"string"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]},"notes":{"type":["string","null"]},"locationIds":{"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"externalSource":{"type":["string","null"]},"externalId":{"type":["string","null"]},"createdAt":{"type":"string","description":"ISO-8601 timestamp"},"updatedAt":{"type":"string","description":"ISO-8601 timestamp"}},"required":["id","type","name","email","phone","notes","locationIds","externalSource","externalId","createdAt","updatedAt"],"additionalProperties":false},"LocationPage":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/$defs/Location"}},"hasMore":{"type":"boolean"},"nextCursor":{"type":["string","null"]}},"required":["data","hasMore","nextCursor"],"additionalProperties":false},"Location":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"customerId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":["string","null"]},"street":{"type":"string"},"city":{"type":["string","null"]},"state":{"type":["string","null"]},"zip":{"type":["string","null"]},"accessNotes":{"type":["string","null"]},"externalSource":{"type":["string","null"]},"externalId":{"type":["string","null"]},"createdAt":{"type":"string","description":"ISO-8601 timestamp"},"updatedAt":{"type":"string","description":"ISO-8601 timestamp"}},"required":["id","customerId","name","street","city","state","zip","accessNotes","externalSource","externalId","createdAt","updatedAt"],"additionalProperties":false},"JobPage":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/$defs/Job"}},"hasMore":{"type":"boolean"},"nextCursor":{"type":["string","null"]}},"required":["data","hasMore","nextCursor"],"additionalProperties":false},"Job":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"number":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"customerId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"locationId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"summary":{"type":"string"},"description":{"type":["string","null"]},"status":{"type":"string","enum":["unscheduled","scheduled","in_progress","follow_up","completed","canceled"]},"priority":{"type":"string","enum":["normal","high","emergency"]},"jobTypeId":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"businessUnitId":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"campaignId":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"externalRef":{"description":"Your reference when the job was booked by another system (idempotent).","type":["string","null"]},"completedAt":{"anyOf":[{"type":"string","description":"ISO-8601 timestamp"},{"type":"null"}]},"externalSource":{"type":["string","null"]},"externalId":{"type":["string","null"]},"createdAt":{"type":"string","description":"ISO-8601 timestamp"},"updatedAt":{"type":"string","description":"ISO-8601 timestamp"}},"required":["id","number","customerId","locationId","summary","description","status","priority","jobTypeId","businessUnitId","campaignId","externalRef","completedAt","externalSource","externalId","createdAt","updatedAt"],"additionalProperties":false},"AppointmentPage":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/$defs/Appointment"}},"hasMore":{"type":"boolean"},"nextCursor":{"type":["string","null"]}},"required":["data","hasMore","nextCursor"],"additionalProperties":false},"Appointment":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"jobId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"status":{"type":"string","enum":["scheduled","dispatched","en_route","working","done","canceled"]},"arrivalStart":{"type":"string","description":"ISO-8601 timestamp"},"arrivalEnd":{"type":"string","description":"ISO-8601 timestamp"},"durationMinutes":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"technicianIds":{"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"instructions":{"type":["string","null"]},"enRouteAt":{"anyOf":[{"type":"string","description":"ISO-8601 timestamp"},{"type":"null"}]},"arrivedAt":{"anyOf":[{"type":"string","description":"ISO-8601 timestamp"},{"type":"null"}]},"completedAt":{"anyOf":[{"type":"string","description":"ISO-8601 timestamp"},{"type":"null"}]},"canceledAt":{"anyOf":[{"type":"string","description":"ISO-8601 timestamp"},{"type":"null"}]},"outcome":{"anyOf":[{"type":"string","enum":["job_complete","follow_up"]},{"type":"null"}]},"externalSource":{"type":["string","null"]},"externalId":{"type":["string","null"]},"createdAt":{"type":"string","description":"ISO-8601 timestamp"},"updatedAt":{"type":"string","description":"ISO-8601 timestamp"}},"required":["id","jobId","status","arrivalStart","arrivalEnd","durationMinutes","technicianIds","instructions","enRouteAt","arrivedAt","completedAt","canceledAt","outcome","externalSource","externalId","createdAt","updatedAt"],"additionalProperties":false},"EstimatePage":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/$defs/Estimate"}},"hasMore":{"type":"boolean"},"nextCursor":{"type":["string","null"]}},"required":["data","hasMore","nextCursor"],"additionalProperties":false},"Estimate":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"jobId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"number":{"type":"string"},"name":{"type":"string"},"summary":{"type":["string","null"]},"status":{"type":"string","enum":["open","sold","dismissed"]},"optionGroup":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"subtotal":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Integer cents"},"tax":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Integer cents"},"total":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Integer cents"},"soldAt":{"anyOf":[{"type":"string","description":"ISO-8601 timestamp"},{"type":"null"}]},"dismissedAt":{"anyOf":[{"type":"string","description":"ISO-8601 timestamp"},{"type":"null"}]},"items":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":["string","null"]},"kind":{"type":"string","enum":["service","material","equipment"]},"quantity":{"type":"number"},"unitPrice":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Integer cents"},"taxable":{"type":"boolean"},"pricebookItemId":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]}},"required":["name","description","kind","quantity","unitPrice","taxable","pricebookItemId"],"additionalProperties":false}},"externalSource":{"type":["string","null"]},"externalId":{"type":["string","null"]},"createdAt":{"type":"string","description":"ISO-8601 timestamp"},"updatedAt":{"type":"string","description":"ISO-8601 timestamp"}},"required":["id","jobId","number","name","summary","status","optionGroup","subtotal","tax","total","soldAt","dismissedAt","items","externalSource","externalId","createdAt","updatedAt"],"additionalProperties":false},"InvoicePage":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/$defs/Invoice"}},"hasMore":{"type":"boolean"},"nextCursor":{"type":["string","null"]}},"required":["data","hasMore","nextCursor"],"additionalProperties":false},"Invoice":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"jobId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"number":{"type":"string"},"status":{"type":"string","enum":["draft","sent","paid","void"]},"subtotal":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Integer cents"},"tax":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Integer cents"},"total":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Integer cents"},"paid":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Integer cents"},"balance":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Integer cents"},"dueOn":{"type":["string","null"]},"sentAt":{"anyOf":[{"type":"string","description":"ISO-8601 timestamp"},{"type":"null"}]},"paidAt":{"anyOf":[{"type":"string","description":"ISO-8601 timestamp"},{"type":"null"}]},"items":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":["string","null"]},"kind":{"type":"string","enum":["service","material","equipment"]},"quantity":{"type":"number"},"unitPrice":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Integer cents"},"taxable":{"type":"boolean"},"pricebookItemId":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]}},"required":["name","description","kind","quantity","unitPrice","taxable","pricebookItemId"],"additionalProperties":false}},"externalSource":{"type":["string","null"]},"externalId":{"type":["string","null"]},"createdAt":{"type":"string","description":"ISO-8601 timestamp"},"updatedAt":{"type":"string","description":"ISO-8601 timestamp"}},"required":["id","jobId","number","status","subtotal","tax","total","paid","balance","dueOn","sentAt","paidAt","items","externalSource","externalId","createdAt","updatedAt"],"additionalProperties":false},"CheckoutLink":{"type":"object","properties":{"url":{"type":"string"}},"required":["url"],"additionalProperties":false},"PaymentPage":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/$defs/Payment"}},"hasMore":{"type":"boolean"},"nextCursor":{"type":["string","null"]}},"required":["data","hasMore","nextCursor"],"additionalProperties":false},"Payment":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"invoiceId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"amount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Integer cents"},"method":{"type":"string","enum":["card","ach","cash","check","other"]},"status":{"type":"string","enum":["pending","succeeded","failed","refunded"]},"reference":{"type":["string","null"]},"memo":{"type":["string","null"]},"receivedAt":{"anyOf":[{"type":"string","description":"ISO-8601 timestamp"},{"type":"null"}]},"externalSource":{"type":["string","null"]},"externalId":{"type":["string","null"]},"createdAt":{"type":"string","description":"ISO-8601 timestamp"},"updatedAt":{"type":"string","description":"ISO-8601 timestamp"}},"required":["id","invoiceId","amount","method","status","reference","memo","receivedAt","externalSource","externalId","createdAt","updatedAt"],"additionalProperties":false},"PricebookItemPage":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/$defs/PricebookItem"}},"hasMore":{"type":"boolean"},"nextCursor":{"type":["string","null"]}},"required":["data","hasMore","nextCursor"],"additionalProperties":false},"PricebookItem":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"kind":{"type":"string","enum":["service","material","equipment"]},"code":{"type":["string","null"]},"name":{"type":"string"},"description":{"type":["string","null"]},"category":{"type":["string","null"]},"unitPrice":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Integer cents"},"taxable":{"type":"boolean"},"active":{"type":"boolean"},"externalSource":{"type":["string","null"]},"externalId":{"type":["string","null"]},"createdAt":{"type":"string","description":"ISO-8601 timestamp"},"updatedAt":{"type":"string","description":"ISO-8601 timestamp"}},"required":["id","kind","code","name","description","category","unitPrice","taxable","active","externalSource","externalId","createdAt","updatedAt"],"additionalProperties":false},"TechnicianList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/$defs/Technician"}}},"required":["data"],"additionalProperties":false},"Technician":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string"},"role":{"type":"string"}},"required":["id","name","role"],"additionalProperties":false},"EventTypeList":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string"},"resource":{"type":"string"},"label":{"type":"string"}},"required":["type","resource","label"],"additionalProperties":false}}},"required":["data"],"additionalProperties":false},"WebhookEndpointList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/$defs/WebhookEndpoint"}}},"required":["data"],"additionalProperties":false},"WebhookEndpoint":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"url":{"type":"string"},"description":{"type":["string","null"]},"eventTypes":{"type":"array","items":{"type":"string"}},"status":{"type":"string","enum":["active","disabled"]},"disabledReason":{"type":["string","null"]},"secretPrefix":{"type":"string"},"createdAt":{"type":"string","description":"ISO-8601 timestamp"}},"required":["id","url","description","eventTypes","status","disabledReason","secretPrefix","createdAt"],"additionalProperties":false},"WebhookEndpointCreated":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"url":{"type":"string"},"description":{"type":["string","null"]},"eventTypes":{"type":"array","items":{"type":"string"}},"status":{"type":"string","enum":["active","disabled"]},"disabledReason":{"type":["string","null"]},"secretPrefix":{"type":"string"},"createdAt":{"type":"string","description":"ISO-8601 timestamp"},"secret":{"type":"string","description":"Signing secret (whsec_…). Shown once: store it to verify the tradesos-signature header."}},"required":["id","url","description","eventTypes","status","disabledReason","secretPrefix","createdAt","secret"],"additionalProperties":false},"Deleted":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"deleted":{"type":"boolean","const":true}},"required":["id","deleted"],"additionalProperties":false},"TestDelivery":{"type":"object","properties":{"deliveryId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"status":{"type":"string"},"responseStatus":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"error":{"type":["string","null"]}},"required":["deliveryId","status","responseStatus","error"],"additionalProperties":false}},"securitySchemes":{"bearer":{"type":"http","scheme":"bearer","description":"Company API key (tos_…). Its scopes: customers:read, jobs:read, jobs:book, reports:read, availability:read, demand:read, demand:respond, customers:write, jobs:write, dispatch:write, estimates:read, invoices:read, payments:write, pricebook:read, technicians:read, webhooks:manage, leads:write, marketing.read, marketing.write, booking.write, audiences.export"},"oauth2":{"type":"oauth2","description":"Authorization code with PKCE (S256).","flows":{"authorizationCode":{"authorizationUrl":"https://tradesos-three.vercel.app/oauth/authorize","tokenUrl":"https://tradesos-three.vercel.app/api/oauth/token","refreshUrl":"https://tradesos-three.vercel.app/api/oauth/token","scopes":{"customers:read":"Look up customers","jobs:read":"Read jobs and their status","jobs:book":"Book new jobs (creates customers and locations)","reports:read":"Read revenue and attribution reports","availability:read":"Read open arrival windows and capacity","demand:read":"Read the demand forecast and demand requests (fill the board, throttle ads)","demand:respond":"Report campaigns launched or declined for demand requests","customers:write":"Create customers and service locations","jobs:write":"Create jobs","dispatch:write":"Schedule, assign and move appointments through their statuses (dispatch, arrive, complete)","estimates:read":"Read estimates","invoices:read":"Read invoices and payments","payments:write":"Record payments and create card payment links","pricebook:read":"Read the price book","technicians:read":"Read the technician list","webhooks:manage":"Subscribe to webhooks (Zapier, n8n and other REST hooks)","leads:write":"Send new leads to the lead inbox (answered by the text agent like any other lead)","marketing.read":"Read campaigns, campaign performance, lead status, conversions, audience counts, capacity and review summaries","marketing.write":"Create and update campaigns, record ad spend and send in new leads","booking.write":"Book jobs and appointments (creates customers and locations)","audiences.export":"Export hashed contact lists of customers who agreed to marketing (only if an owner turns it on)"}}}}}}}