{"openapi":"3.1.0","info":{"title":"CalSpark API","version":"2026-10-01","description":"Public REST API for CalSpark. Authenticate with a Bearer API key created in Settings > Developers. Money is integer cents, timestamps are ISO 8601 UTC. Default rate limit: 120 requests per minute per key."},"servers":[{"url":"https://service-scheduler-web.vercel.app/api/v1"}],"tags":[{"name":"Account"},{"name":"Customers"},{"name":"Jobs"},{"name":"Invoices"},{"name":"Estimates"},{"name":"Payments"},{"name":"Users"},{"name":"Events"},{"name":"Webhook endpoints"},{"name":"Meta"}],"paths":{"/me":{"get":{"operationId":"getMe","tags":["Account"],"summary":"Who am I","description":"Returns the company and API key behind the presented key. Works with any valid key.","responses":{"200":{"description":"Success.","headers":{"Request-Id":{"description":"Unique id of this request (req_...). Quote it to support.","schema":{"type":"string"}},"RateLimit-Limit":{"description":"Requests allowed per minute for this key.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Unix time (seconds) when the window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Me"}}}},"400":{"description":"invalid_request or invalid_cursor.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"authentication_required or invalid_api_key (missing, malformed, unknown, revoked or expired key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"subscription_required: the company subscription is not active.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, or feature_disabled when the company does not have this feature.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited. See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearerAuth":[]}]}},"/customers":{"get":{"operationId":"getCustomers","tags":["Customers"],"summary":"List customers","parameters":[{"name":"limit","in":"query","required":false,"description":"Page size, 1 to 100 (default 25).","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","required":false,"description":"Opaque cursor from a previous response. An invalid cursor returns 400 invalid_cursor.","schema":{"type":"string"}},{"name":"email","in":"query","required":false,"description":"Exact (case-insensitive) email match.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","headers":{"Request-Id":{"description":"Unique id of this request (req_...). Quote it to support.","schema":{"type":"string"}},"RateLimit-Limit":{"description":"Requests allowed per minute for this key.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Unix time (seconds) when the window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerList"}}}},"400":{"description":"invalid_request or invalid_cursor.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"authentication_required or invalid_api_key (missing, malformed, unknown, revoked or expired key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"subscription_required: the company subscription is not active.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, or feature_disabled when the company does not have this feature.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited. See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearerAuth":["customers:read"]}],"x-required-scope":"customers:read"},"post":{"operationId":"postCustomers","tags":["Customers"],"summary":"Create a customer","description":"Does not de-duplicate. Sets source to api. sms_consent is recorded only when true with sms_consent_source.","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Unique key (8 to 128 chars: letters, digits, _ - : .). Retrying with the same key and body replays the stored response (Idempotent-Replayed: true); the same key with a different body returns 409 idempotency_key_reuse. Kept 24 hours.","schema":{"type":"string","minLength":8,"maxLength":128}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomerRequest"}}}},"responses":{"201":{"description":"Success.","headers":{"Request-Id":{"description":"Unique id of this request (req_...). Quote it to support.","schema":{"type":"string"}},"RateLimit-Limit":{"description":"Requests allowed per minute for this key.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Unix time (seconds) when the window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Customer"}}}},"400":{"description":"invalid_request or invalid_cursor.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"authentication_required or invalid_api_key (missing, malformed, unknown, revoked or expired key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"subscription_required: the company subscription is not active.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, or feature_disabled when the company does not have this feature.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"conflict, idempotency_key_reuse or idempotency_in_progress.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"payload_too_large: the request body is over 256KB.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed. See error.details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited. See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearerAuth":["customers:write"]}],"x-required-scope":"customers:write"}},"/customers/{id}":{"get":{"operationId":"getCustomersId","tags":["Customers"],"summary":"Get a customer","parameters":[{"name":"id","in":"path","required":true,"description":"Customers id.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","headers":{"Request-Id":{"description":"Unique id of this request (req_...). Quote it to support.","schema":{"type":"string"}},"RateLimit-Limit":{"description":"Requests allowed per minute for this key.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Unix time (seconds) when the window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Customer"}}}},"400":{"description":"invalid_request or invalid_cursor.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"authentication_required or invalid_api_key (missing, malformed, unknown, revoked or expired key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"subscription_required: the company subscription is not active.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, or feature_disabled when the company does not have this feature.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not_found. Also returned for ids that belong to another company.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited. See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearerAuth":["customers:read"]}],"x-required-scope":"customers:read"}},"/jobs":{"get":{"operationId":"getJobs","tags":["Jobs"],"summary":"List jobs","parameters":[{"name":"limit","in":"query","required":false,"description":"Page size, 1 to 100 (default 25).","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","required":false,"description":"Opaque cursor from a previous response. An invalid cursor returns 400 invalid_cursor.","schema":{"type":"string"}},{"name":"status","in":"query","required":false,"description":"Filter by status.","schema":{"type":"string","enum":["pending","scheduled","in_progress","completed","cancelled"]}},{"name":"customer_id","in":"query","required":false,"description":"Filter by customer id.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","headers":{"Request-Id":{"description":"Unique id of this request (req_...). Quote it to support.","schema":{"type":"string"}},"RateLimit-Limit":{"description":"Requests allowed per minute for this key.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Unix time (seconds) when the window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobList"}}}},"400":{"description":"invalid_request or invalid_cursor.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"authentication_required or invalid_api_key (missing, malformed, unknown, revoked or expired key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"subscription_required: the company subscription is not active.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, or feature_disabled when the company does not have this feature.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited. See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearerAuth":["jobs:read"]}],"x-required-scope":"jobs:read"},"post":{"operationId":"postJobs","tags":["Jobs"],"summary":"Create a job","description":"customer_id and address_id must belong to your company. With scheduled_start and scheduled_end the job is created as scheduled, otherwise pending.","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Unique key (8 to 128 chars: letters, digits, _ - : .). Retrying with the same key and body replays the stored response (Idempotent-Replayed: true); the same key with a different body returns 409 idempotency_key_reuse. Kept 24 hours.","schema":{"type":"string","minLength":8,"maxLength":128}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateJobRequest"}}}},"responses":{"201":{"description":"Success.","headers":{"Request-Id":{"description":"Unique id of this request (req_...). Quote it to support.","schema":{"type":"string"}},"RateLimit-Limit":{"description":"Requests allowed per minute for this key.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Unix time (seconds) when the window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Job"}}}},"400":{"description":"invalid_request or invalid_cursor.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"authentication_required or invalid_api_key (missing, malformed, unknown, revoked or expired key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"subscription_required: the company subscription is not active.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, or feature_disabled when the company does not have this feature.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not_found. Also returned for ids that belong to another company.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"conflict, idempotency_key_reuse or idempotency_in_progress.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"payload_too_large: the request body is over 256KB.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed. See error.details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited. See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearerAuth":["jobs:write"]}],"x-required-scope":"jobs:write"}},"/jobs/{id}":{"get":{"operationId":"getJobsId","tags":["Jobs"],"summary":"Get a job","parameters":[{"name":"id","in":"path","required":true,"description":"Jobs id.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","headers":{"Request-Id":{"description":"Unique id of this request (req_...). Quote it to support.","schema":{"type":"string"}},"RateLimit-Limit":{"description":"Requests allowed per minute for this key.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Unix time (seconds) when the window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Job"}}}},"400":{"description":"invalid_request or invalid_cursor.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"authentication_required or invalid_api_key (missing, malformed, unknown, revoked or expired key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"subscription_required: the company subscription is not active.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, or feature_disabled when the company does not have this feature.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not_found. Also returned for ids that belong to another company.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited. See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearerAuth":["jobs:read"]}],"x-required-scope":"jobs:read"}},"/invoices":{"get":{"operationId":"getInvoices","tags":["Invoices"],"summary":"List invoices","parameters":[{"name":"limit","in":"query","required":false,"description":"Page size, 1 to 100 (default 25).","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","required":false,"description":"Opaque cursor from a previous response. An invalid cursor returns 400 invalid_cursor.","schema":{"type":"string"}},{"name":"status","in":"query","required":false,"description":"Filter by status.","schema":{"type":"string","enum":["draft","sent","viewed","paid","partially_paid","overdue","void","uncollectible"]}},{"name":"customer_id","in":"query","required":false,"description":"Filter by customer id.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","headers":{"Request-Id":{"description":"Unique id of this request (req_...). Quote it to support.","schema":{"type":"string"}},"RateLimit-Limit":{"description":"Requests allowed per minute for this key.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Unix time (seconds) when the window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvoiceList"}}}},"400":{"description":"invalid_request or invalid_cursor.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"authentication_required or invalid_api_key (missing, malformed, unknown, revoked or expired key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"subscription_required: the company subscription is not active.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, or feature_disabled when the company does not have this feature.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited. See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearerAuth":["invoices:read"]}],"x-required-scope":"invoices:read"},"post":{"operationId":"postInvoices","tags":["Invoices"],"summary":"Create a draft invoice","description":"Creates a draft only. Money is integer cents; totals are computed by the server. Sending and collecting payment happen in CalSpark.","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Unique key (8 to 128 chars: letters, digits, _ - : .). Retrying with the same key and body replays the stored response (Idempotent-Replayed: true); the same key with a different body returns 409 idempotency_key_reuse. Kept 24 hours.","schema":{"type":"string","minLength":8,"maxLength":128}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateInvoiceRequest"}}}},"responses":{"201":{"description":"Success.","headers":{"Request-Id":{"description":"Unique id of this request (req_...). Quote it to support.","schema":{"type":"string"}},"RateLimit-Limit":{"description":"Requests allowed per minute for this key.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Unix time (seconds) when the window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Invoice"}}}},"400":{"description":"invalid_request or invalid_cursor.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"authentication_required or invalid_api_key (missing, malformed, unknown, revoked or expired key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"subscription_required: the company subscription is not active.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, or feature_disabled when the company does not have this feature.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not_found. Also returned for ids that belong to another company.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"conflict, idempotency_key_reuse or idempotency_in_progress.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"payload_too_large: the request body is over 256KB.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed. See error.details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited. See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearerAuth":["invoices:write"]}],"x-required-scope":"invoices:write"}},"/invoices/{id}":{"get":{"operationId":"getInvoicesId","tags":["Invoices"],"summary":"Get an invoice","parameters":[{"name":"id","in":"path","required":true,"description":"Invoices id.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","headers":{"Request-Id":{"description":"Unique id of this request (req_...). Quote it to support.","schema":{"type":"string"}},"RateLimit-Limit":{"description":"Requests allowed per minute for this key.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Unix time (seconds) when the window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Invoice"}}}},"400":{"description":"invalid_request or invalid_cursor.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"authentication_required or invalid_api_key (missing, malformed, unknown, revoked or expired key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"subscription_required: the company subscription is not active.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, or feature_disabled when the company does not have this feature.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not_found. Also returned for ids that belong to another company.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited. See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearerAuth":["invoices:read"]}],"x-required-scope":"invoices:read"}},"/estimates":{"get":{"operationId":"getEstimates","tags":["Estimates"],"summary":"List estimates","description":"Read-only. Estimates are created, sent and converted in CalSpark; the customer approval link is never returned. total is integer cents; expires_on is a calendar date in the company time zone.","parameters":[{"name":"limit","in":"query","required":false,"description":"Page size, 1 to 100 (default 25).","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","required":false,"description":"Opaque cursor from a previous response. An invalid cursor returns 400 invalid_cursor.","schema":{"type":"string"}},{"name":"status","in":"query","required":false,"description":"Filter by status.","schema":{"type":"string","enum":["draft","sent","viewed","approved","declined","expired"]}},{"name":"customer_id","in":"query","required":false,"description":"Filter by customer id.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","headers":{"Request-Id":{"description":"Unique id of this request (req_...). Quote it to support.","schema":{"type":"string"}},"RateLimit-Limit":{"description":"Requests allowed per minute for this key.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Unix time (seconds) when the window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EstimateList"}}}},"400":{"description":"invalid_request or invalid_cursor.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"authentication_required or invalid_api_key (missing, malformed, unknown, revoked or expired key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"subscription_required: the company subscription is not active.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, or feature_disabled when the company does not have this feature.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited. See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearerAuth":["estimates:read"]}],"x-required-scope":"estimates:read"}},"/estimates/{id}":{"get":{"operationId":"getEstimatesId","tags":["Estimates"],"summary":"Get an estimate","parameters":[{"name":"id","in":"path","required":true,"description":"Estimates id.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","headers":{"Request-Id":{"description":"Unique id of this request (req_...). Quote it to support.","schema":{"type":"string"}},"RateLimit-Limit":{"description":"Requests allowed per minute for this key.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Unix time (seconds) when the window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Estimate"}}}},"400":{"description":"invalid_request or invalid_cursor.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"authentication_required or invalid_api_key (missing, malformed, unknown, revoked or expired key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"subscription_required: the company subscription is not active.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, or feature_disabled when the company does not have this feature.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not_found. Also returned for ids that belong to another company.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited. See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearerAuth":["estimates:read"]}],"x-required-scope":"estimates:read"}},"/payments":{"get":{"operationId":"getPayments","tags":["Payments"],"summary":"List payments","parameters":[{"name":"limit","in":"query","required":false,"description":"Page size, 1 to 100 (default 25).","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","required":false,"description":"Opaque cursor from a previous response. An invalid cursor returns 400 invalid_cursor.","schema":{"type":"string"}},{"name":"invoice_id","in":"query","required":false,"description":"Filter by invoice id.","schema":{"type":"string"}},{"name":"status","in":"query","required":false,"description":"Filter by status.","schema":{"type":"string","enum":["pending","processing","completed","failed","refunded"]}}],"responses":{"200":{"description":"Success.","headers":{"Request-Id":{"description":"Unique id of this request (req_...). Quote it to support.","schema":{"type":"string"}},"RateLimit-Limit":{"description":"Requests allowed per minute for this key.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Unix time (seconds) when the window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentList"}}}},"400":{"description":"invalid_request or invalid_cursor.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"authentication_required or invalid_api_key (missing, malformed, unknown, revoked or expired key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"subscription_required: the company subscription is not active.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, or feature_disabled when the company does not have this feature.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited. See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearerAuth":["payments:read"]}],"x-required-scope":"payments:read"}},"/payments/{id}":{"get":{"operationId":"getPaymentsId","tags":["Payments"],"summary":"Get a payment","parameters":[{"name":"id","in":"path","required":true,"description":"Payments id.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","headers":{"Request-Id":{"description":"Unique id of this request (req_...). Quote it to support.","schema":{"type":"string"}},"RateLimit-Limit":{"description":"Requests allowed per minute for this key.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Unix time (seconds) when the window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Payment"}}}},"400":{"description":"invalid_request or invalid_cursor.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"authentication_required or invalid_api_key (missing, malformed, unknown, revoked or expired key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"subscription_required: the company subscription is not active.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, or feature_disabled when the company does not have this feature.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not_found. Also returned for ids that belong to another company.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited. See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearerAuth":["payments:read"]}],"x-required-scope":"payments:read"}},"/users":{"get":{"operationId":"getUsers","tags":["Users"],"summary":"List team members","description":"Disabled users are excluded unless include_disabled=true. Phone numbers are never returned.","parameters":[{"name":"limit","in":"query","required":false,"description":"Page size, 1 to 100 (default 25).","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","required":false,"description":"Opaque cursor from a previous response. An invalid cursor returns 400 invalid_cursor.","schema":{"type":"string"}},{"name":"include_disabled","in":"query","required":false,"description":"Set to true to include disabled users.","schema":{"type":"string","enum":["true"]}}],"responses":{"200":{"description":"Success.","headers":{"Request-Id":{"description":"Unique id of this request (req_...). Quote it to support.","schema":{"type":"string"}},"RateLimit-Limit":{"description":"Requests allowed per minute for this key.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Unix time (seconds) when the window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserList"}}}},"400":{"description":"invalid_request or invalid_cursor.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"authentication_required or invalid_api_key (missing, malformed, unknown, revoked or expired key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"subscription_required: the company subscription is not active.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, or feature_disabled when the company does not have this feature.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited. See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearerAuth":["users:read"]}],"x-required-scope":"users:read"}},"/users/{id}":{"get":{"operationId":"getUsersId","tags":["Users"],"summary":"Get a team member","parameters":[{"name":"id","in":"path","required":true,"description":"Users id.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","headers":{"Request-Id":{"description":"Unique id of this request (req_...). Quote it to support.","schema":{"type":"string"}},"RateLimit-Limit":{"description":"Requests allowed per minute for this key.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Unix time (seconds) when the window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/User"}}}},"400":{"description":"invalid_request or invalid_cursor.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"authentication_required or invalid_api_key (missing, malformed, unknown, revoked or expired key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"subscription_required: the company subscription is not active.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, or feature_disabled when the company does not have this feature.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not_found. Also returned for ids that belong to another company.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited. See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearerAuth":["users:read"]}],"x-required-scope":"users:read"}},"/events":{"get":{"operationId":"getEvents","tags":["Events"],"summary":"Poll events","description":"Oldest first. Pass the returned next_cursor to continue; it is returned whenever data is non-empty (even when has_more is false), so a poller keeps its position. Events appear after a short settle window (about 2 seconds).","parameters":[{"name":"limit","in":"query","required":false,"description":"Page size, 1 to 100 (default 25).","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","required":false,"description":"Opaque cursor from a previous response. An invalid cursor returns 400 invalid_cursor.","schema":{"type":"string"}},{"name":"type","in":"query","required":false,"description":"Only this event type.","schema":{"type":"string","enum":["customer.created","customer.updated","customer.deleted","job.created","job.scheduled","job.rescheduled","job.unscheduled","job.assigned","job.unassigned","job.en_route","job.status_changed","job.completed","job.cancelled","job.deleted","job.photo_added","invoice.created","invoice.sent","invoice.viewed","invoice.paid","invoice.partially_paid","invoice.overdue","invoice.voided","invoice.updated","payment.received","payment.failed","payment.refunded","lead.created","estimate.sent","estimate.viewed","estimate.approved","estimate.declined","estimate.converted"]}},{"name":"order","in":"query","required":false,"description":"asc (default, oldest first, for pollers) or desc (newest first, for \"the latest N\"; next_cursor then pages toward older events and is null on the last page).","schema":{"type":"string","enum":["asc","desc"]}}],"responses":{"200":{"description":"Success.","headers":{"Request-Id":{"description":"Unique id of this request (req_...). Quote it to support.","schema":{"type":"string"}},"RateLimit-Limit":{"description":"Requests allowed per minute for this key.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Unix time (seconds) when the window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EventList"}}}},"400":{"description":"invalid_request or invalid_cursor.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"authentication_required or invalid_api_key (missing, malformed, unknown, revoked or expired key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"subscription_required: the company subscription is not active.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, or feature_disabled when the company does not have this feature.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited. See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearerAuth":["events:read"]}],"x-required-scope":"events:read"}},"/webhook-endpoints":{"get":{"operationId":"getWebhookEndpoints","tags":["Webhook endpoints"],"summary":"List webhook endpoints","responses":{"200":{"description":"Success.","headers":{"Request-Id":{"description":"Unique id of this request (req_...). Quote it to support.","schema":{"type":"string"}},"RateLimit-Limit":{"description":"Requests allowed per minute for this key.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Unix time (seconds) when the window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpointList"}}}},"400":{"description":"invalid_request or invalid_cursor.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"authentication_required or invalid_api_key (missing, malformed, unknown, revoked or expired key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"subscription_required: the company subscription is not active.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, or feature_disabled when the company does not have this feature.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited. See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearerAuth":["webhooks:manage"]}],"x-required-scope":"webhooks:manage"},"post":{"operationId":"postWebhookEndpoints","tags":["Webhook endpoints"],"summary":"Create a webhook endpoint","description":"The signing secret is returned once. Idempotency-Key is not supported on this operation because the response contains a secret.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWebhookEndpointRequest"}}}},"responses":{"201":{"description":"Success.","headers":{"Request-Id":{"description":"Unique id of this request (req_...). Quote it to support.","schema":{"type":"string"}},"RateLimit-Limit":{"description":"Requests allowed per minute for this key.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Unix time (seconds) when the window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpointCreated"}}}},"400":{"description":"invalid_request or invalid_cursor.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"authentication_required or invalid_api_key (missing, malformed, unknown, revoked or expired key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"subscription_required: the company subscription is not active.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, or feature_disabled when the company does not have this feature.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"payload_too_large: the request body is over 256KB.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed. See error.details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited. See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearerAuth":["webhooks:manage"]}],"x-required-scope":"webhooks:manage"}},"/webhook-endpoints/{id}":{"get":{"operationId":"getWebhookEndpointsId","tags":["Webhook endpoints"],"summary":"Get a webhook endpoint","parameters":[{"name":"id","in":"path","required":true,"description":"Webhook endpoints id.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","headers":{"Request-Id":{"description":"Unique id of this request (req_...). Quote it to support.","schema":{"type":"string"}},"RateLimit-Limit":{"description":"Requests allowed per minute for this key.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Unix time (seconds) when the window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpoint"}}}},"400":{"description":"invalid_request or invalid_cursor.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"authentication_required or invalid_api_key (missing, malformed, unknown, revoked or expired key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"subscription_required: the company subscription is not active.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, or feature_disabled when the company does not have this feature.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not_found. Also returned for ids that belong to another company.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited. See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearerAuth":["webhooks:manage"]}],"x-required-scope":"webhooks:manage"},"patch":{"operationId":"patchWebhookEndpointsId","tags":["Webhook endpoints"],"summary":"Update a webhook endpoint","parameters":[{"name":"id","in":"path","required":true,"description":"Webhook endpoints id.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateWebhookEndpointRequest"}}}},"responses":{"200":{"description":"Success.","headers":{"Request-Id":{"description":"Unique id of this request (req_...). Quote it to support.","schema":{"type":"string"}},"RateLimit-Limit":{"description":"Requests allowed per minute for this key.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Unix time (seconds) when the window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpoint"}}}},"400":{"description":"invalid_request or invalid_cursor.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"authentication_required or invalid_api_key (missing, malformed, unknown, revoked or expired key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"subscription_required: the company subscription is not active.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, or feature_disabled when the company does not have this feature.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not_found. Also returned for ids that belong to another company.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"payload_too_large: the request body is over 256KB.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"validation_failed. See error.details.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited. See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearerAuth":["webhooks:manage"]}],"x-required-scope":"webhooks:manage"},"delete":{"operationId":"deleteWebhookEndpointsId","tags":["Webhook endpoints"],"summary":"Delete a webhook endpoint","parameters":[{"name":"id","in":"path","required":true,"description":"Webhook endpoints id.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success.","headers":{"Request-Id":{"description":"Unique id of this request (req_...). Quote it to support.","schema":{"type":"string"}},"RateLimit-Limit":{"description":"Requests allowed per minute for this key.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in the current window.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Unix time (seconds) when the window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeletedWebhookEndpoint"}}}},"400":{"description":"invalid_request or invalid_cursor.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"authentication_required or invalid_api_key (missing, malformed, unknown, revoked or expired key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"subscription_required: the company subscription is not active.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"insufficient_scope, or feature_disabled when the company does not have this feature.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not_found. Also returned for ids that belong to another company.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited. See Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearerAuth":["webhooks:manage"]}],"x-required-scope":"webhooks:manage"}},"/openapi.json":{"get":{"operationId":"getOpenapiJson","tags":["Meta"],"summary":"This document","description":"Public, no key required.","responses":{"200":{"description":"Success.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenApiDocument"}}}},"500":{"description":"internal_error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[]}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"csk_live_...","description":"API key. Scopes: customers:read, customers:write, jobs:read, jobs:write, invoices:read, invoices:write, estimates:read, payments:read, users:read, events:read, webhooks:manage."}},"schemas":{"Customer":{"type":"object","properties":{"id":{"type":"string"},"object":{"type":"string","const":"customer"},"first_name":{"anyOf":[{"type":"string"},{"type":"null"}]},"last_name":{"anyOf":[{"type":"string"},{"type":"null"}]},"company_name":{"anyOf":[{"type":"string"},{"type":"null"}]},"email":{"anyOf":[{"type":"string"},{"type":"null"}]},"phone":{"anyOf":[{"type":"string"},{"type":"null"}]},"customer_type":{"anyOf":[{"type":"string","enum":["residential","commercial"]},{"type":"null"}]},"created":{"type":"string"},"updated":{"type":"string"}},"required":["id","object","first_name","last_name","company_name","email","phone","customer_type","created","updated"],"additionalProperties":false},"Job":{"type":"object","properties":{"id":{"type":"string"},"object":{"type":"string","const":"job"},"customer_id":{"type":"string"},"address_id":{"anyOf":[{"type":"string"},{"type":"null"}]},"scope_of_work":{"type":"string"},"status":{"type":"string","enum":["pending","scheduled","in_progress","completed","cancelled"]},"scheduled_start":{"anyOf":[{"type":"string"},{"type":"null"}]},"scheduled_end":{"anyOf":[{"type":"string"},{"type":"null"}]},"actual_start":{"anyOf":[{"type":"string"},{"type":"null"}]},"actual_end":{"anyOf":[{"type":"string"},{"type":"null"}]},"en_route_at":{"anyOf":[{"type":"string"},{"type":"null"}]},"assigned_user_ids":{"type":"array","items":{"type":"string"}},"created":{"type":"string"},"updated":{"type":"string"}},"required":["id","object","customer_id","address_id","scope_of_work","status","scheduled_start","scheduled_end","actual_start","actual_end","en_route_at","assigned_user_ids","created","updated"],"additionalProperties":false},"Invoice":{"type":"object","properties":{"id":{"type":"string"},"object":{"type":"string","const":"invoice"},"number":{"type":"string"},"customer_id":{"type":"string"},"job_id":{"anyOf":[{"type":"string"},{"type":"null"}]},"status":{"type":"string","enum":["draft","sent","viewed","paid","partially_paid","overdue","void","uncollectible"]},"currency":{"type":"string","const":"usd"},"subtotal":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"tax":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"discount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"total":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"amount_paid":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"amount_due":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"invoice_date":{"type":"string"},"due_date":{"description":"Due date as a calendar date (YYYY-MM-DD) in the company time zone, not an instant.","type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},"paid_at":{"anyOf":[{"type":"string"},{"type":"null"}]},"sent_at":{"anyOf":[{"type":"string"},{"type":"null"}]},"created":{"type":"string"},"updated":{"type":"string"}},"required":["id","object","number","customer_id","job_id","status","currency","subtotal","tax","discount","total","amount_paid","amount_due","invoice_date","due_date","paid_at","sent_at","created","updated"],"additionalProperties":false},"Estimate":{"type":"object","properties":{"id":{"type":"string"},"object":{"type":"string","const":"estimate"},"estimate_number":{"type":"string"},"status":{"type":"string","enum":["draft","sent","viewed","approved","declined","expired"]},"customer_id":{"type":"string"},"total":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"currency":{"type":"string","const":"usd"},"expires_on":{"description":"Expiry as a calendar date (YYYY-MM-DD) in the company time zone, or null for none.","anyOf":[{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},{"type":"null"}]},"decided_by_name":{"anyOf":[{"type":"string"},{"type":"null"}]},"decline_reason":{"anyOf":[{"type":"string"},{"type":"null"}]},"converted_job_id":{"anyOf":[{"type":"string"},{"type":"null"}]},"converted_invoice_id":{"anyOf":[{"type":"string"},{"type":"null"}]},"created_at":{"type":"string"}},"required":["id","object","estimate_number","status","customer_id","total","currency","expires_on","decided_by_name","decline_reason","converted_job_id","converted_invoice_id","created_at"],"additionalProperties":false},"Payment":{"type":"object","properties":{"id":{"type":"string"},"object":{"type":"string","const":"payment"},"invoice_id":{"type":"string"},"amount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"currency":{"type":"string","const":"usd"},"method":{"type":"string","enum":["card","cash","check","ach","other"]},"status":{"type":"string","enum":["pending","processing","completed","failed","refunded"]},"paid_at":{"type":"string"},"created":{"type":"string"}},"required":["id","object","invoice_id","amount","currency","method","status","paid_at","created"],"additionalProperties":false},"User":{"type":"object","properties":{"id":{"type":"string"},"object":{"type":"string","const":"user"},"first_name":{"type":"string"},"last_name":{"type":"string"},"email":{"type":"string"},"role":{"description":"Lower-cased role: company_admin, front_office or service_technician.","type":"string"},"disabled":{"type":"boolean"},"created":{"type":"string"}},"required":["id","object","first_name","last_name","email","role","disabled","created"],"additionalProperties":false},"WebhookEndpoint":{"type":"object","properties":{"id":{"type":"string"},"object":{"type":"string","const":"webhook_endpoint"},"url":{"type":"string"},"description":{"anyOf":[{"type":"string"},{"type":"null"}]},"event_types":{"description":"Empty list means every event type.","type":"array","items":{"type":"string"}},"enabled":{"type":"boolean"},"disabled_reason":{"anyOf":[{"type":"string"},{"type":"null"}]},"created":{"type":"string"},"updated":{"type":"string"}},"required":["id","object","url","description","event_types","enabled","disabled_reason","created","updated"],"additionalProperties":false},"WebhookEndpointCreated":{"type":"object","properties":{"id":{"type":"string"},"object":{"type":"string","const":"webhook_endpoint"},"url":{"type":"string"},"description":{"anyOf":[{"type":"string"},{"type":"null"}]},"event_types":{"description":"Empty list means every event type.","type":"array","items":{"type":"string"}},"enabled":{"type":"boolean"},"disabled_reason":{"anyOf":[{"type":"string"},{"type":"null"}]},"created":{"type":"string"},"updated":{"type":"string"},"secret":{"description":"Signing secret. Returned once, on creation only.","type":"string"}},"required":["id","object","url","description","event_types","enabled","disabled_reason","created","updated","secret"],"additionalProperties":false},"Event":{"type":"object","properties":{"id":{"type":"string","pattern":"^evt_[a-f0-9]{32}$"},"type":{"type":"string"},"api_version":{"type":"string"},"created":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"company_id":{"type":"string","minLength":1},"data":{"type":"object","properties":{"object":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"previous_attributes":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"required":["object","previous_attributes"],"additionalProperties":false}},"required":["id","type","api_version","created","company_id","data"],"additionalProperties":false},"Me":{"type":"object","properties":{"object":{"type":"string","const":"me"},"company":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"timezone":{"type":"string"}},"required":["id","name","timezone"],"additionalProperties":false},"api_key":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"scopes":{"type":"array","items":{"type":"string"}}},"required":["id","name","scopes"],"additionalProperties":false}},"required":["object","company","api_key"],"additionalProperties":false},"DeletedWebhookEndpoint":{"type":"object","properties":{"id":{"type":"string"},"object":{"type":"string","const":"webhook_endpoint"},"deleted":{"type":"boolean","const":true}},"required":["id","object","deleted"],"additionalProperties":false},"CreateCustomerRequest":{"type":"object","properties":{"first_name":{"anyOf":[{"type":"string","minLength":1,"maxLength":100},{"type":"null"}]},"last_name":{"anyOf":[{"type":"string","minLength":1,"maxLength":100},{"type":"null"}]},"company_name":{"anyOf":[{"type":"string","minLength":1,"maxLength":200},{"type":"null"}]},"email":{"anyOf":[{"type":"string","maxLength":254,"format":"email","pattern":"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},{"type":"null"}]},"phone":{"anyOf":[{"type":"string","minLength":3,"maxLength":40},{"type":"null"}]},"sms_consent":{"type":"boolean"},"sms_consent_source":{"type":"string","minLength":1,"maxLength":100}},"additionalProperties":false},"CreateJobRequest":{"type":"object","properties":{"customer_id":{"anyOf":[{"type":"string","pattern":"^\\d{1,10}$"},{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991}]},"address_id":{"anyOf":[{"type":"string","minLength":1,"maxLength":64},{"type":"null"}]},"scope_of_work":{"type":"string","minLength":1,"maxLength":5000},"scheduled_start":{"type":"string"},"scheduled_end":{"type":"string"},"notes":{"type":"string","maxLength":5000}},"required":["customer_id","scope_of_work"],"additionalProperties":false},"CreateInvoiceRequest":{"type":"object","properties":{"customer_id":{"anyOf":[{"type":"string","pattern":"^\\d{1,10}$"},{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991}]},"job_id":{"anyOf":[{"anyOf":[{"type":"string","pattern":"^\\d{1,10}$"},{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991}]},{"type":"null"}]},"line_items":{"minItems":1,"maxItems":100,"type":"array","items":{"type":"object","properties":{"description":{"type":"string","minLength":1,"maxLength":500},"quantity":{"type":"number","exclusiveMinimum":0,"maximum":1000000},"unit_amount":{"type":"integer","minimum":0,"maximum":100000000}},"required":["description","quantity","unit_amount"],"additionalProperties":false}},"tax_rate":{"description":"Tax rate in percent, e.g. 8.25. When omitted, the company default tax rate is applied; send 0 explicitly for no tax.","type":"number","minimum":0,"maximum":100},"discount":{"type":"integer","minimum":0,"maximum":10000000000},"invoice_date":{"type":"string"},"due_date":{"type":"string"}},"required":["customer_id","line_items"],"additionalProperties":false},"CreateWebhookEndpointRequest":{"type":"object","properties":{"url":{"type":"string","maxLength":2048,"format":"uri"},"description":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}]},"event_types":{"maxItems":100,"type":"array","items":{"type":"string"}}},"required":["url"],"additionalProperties":false},"UpdateWebhookEndpointRequest":{"type":"object","properties":{"url":{"type":"string","maxLength":2048,"format":"uri"},"description":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}]},"event_types":{"maxItems":100,"type":"array","items":{"type":"string"}},"enabled":{"type":"boolean"}},"additionalProperties":false},"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["type","code","message","request_id"],"properties":{"type":{"type":"string","enum":["invalid_request_error","authentication_error","permission_error","not_found_error","conflict_error","rate_limit_error","api_error"]},"code":{"type":"string","enum":["invalid_request","validation_failed","authentication_required","invalid_api_key","insufficient_scope","feature_disabled","subscription_required","not_found","payload_too_large","conflict","idempotency_key_reuse","idempotency_in_progress","invalid_cursor","rate_limited","internal_error"]},"message":{"type":"string"},"param":{"type":"string"},"request_id":{"type":"string"},"details":{"type":"array","items":{"type":"object","required":["param","message"],"properties":{"param":{"type":"string"},"message":{"type":"string"}}}}}}}},"OpenApiDocument":{"type":"object"},"CustomerList":{"type":"object","required":["object","data","has_more","next_cursor"],"properties":{"object":{"const":"list"},"data":{"type":"array","items":{"$ref":"#/components/schemas/Customer"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"]}}},"JobList":{"type":"object","required":["object","data","has_more","next_cursor"],"properties":{"object":{"const":"list"},"data":{"type":"array","items":{"$ref":"#/components/schemas/Job"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"]}}},"InvoiceList":{"type":"object","required":["object","data","has_more","next_cursor"],"properties":{"object":{"const":"list"},"data":{"type":"array","items":{"$ref":"#/components/schemas/Invoice"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"]}}},"EstimateList":{"type":"object","required":["object","data","has_more","next_cursor"],"properties":{"object":{"const":"list"},"data":{"type":"array","items":{"$ref":"#/components/schemas/Estimate"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"]}}},"PaymentList":{"type":"object","required":["object","data","has_more","next_cursor"],"properties":{"object":{"const":"list"},"data":{"type":"array","items":{"$ref":"#/components/schemas/Payment"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"]}}},"UserList":{"type":"object","required":["object","data","has_more","next_cursor"],"properties":{"object":{"const":"list"},"data":{"type":"array","items":{"$ref":"#/components/schemas/User"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"]}}},"WebhookEndpointList":{"type":"object","required":["object","data","has_more","next_cursor"],"properties":{"object":{"const":"list"},"data":{"type":"array","items":{"$ref":"#/components/schemas/WebhookEndpoint"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"]}}},"EventList":{"type":"object","required":["object","data","has_more","next_cursor"],"properties":{"object":{"const":"list"},"data":{"type":"array","items":{"$ref":"#/components/schemas/Event"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"]}}}}},"security":[{"bearerAuth":[]}]}