{"openapi":"3.0.3","info":{"title":"WildPipe Tenant API","version":"1.35.0","description":"The WildPipe API gives you programmatic access to the same customers, jobs, visits, quotes, invoices, payments and leads your team works with every day. **Your data is yours** — read it, sync it, and connect it to the rest of your business.\n\n## Base URL\n\nAll requests use HTTPS and JSON:\n\n```\nhttps://api.wildpipe.com/v1\n```\n\n## Authentication\n\nCreate an API key in WildPipe under **Settings → API Keys & Integrations** (owners and admins only). Send it on every request in the `X-API-Key` header:\n\n```bash\ncurl https://api.wildpipe.com/v1/contacts?limit=5 \\\n  -H \"X-API-Key: YOUR_API_KEY\"\n```\n\nEach key carries explicit scopes such as `read:contacts` or `write:leads`, and may be restricted to specific companies. A request outside the key's scopes returns `403` with the `required_scope`. Keep keys server-side and never put them in browser code.\n\n## Pagination\n\nList endpoints return up to `limit` records (1–100, default 25), ordered by `created_at` then `id`. Pass `sort=-created_at` for newest first.\n\n```json\n{ \"data\": [ ... ], \"next_cursor\": \"eyJyZXNvdXJjZSI6...\", \"has_more\": true }\n```\n\nTo get the next page, send `cursor=<next_cursor>` with **the same filters and sort**. Stop when `has_more` is `false`.\n\n## Syncing changes\n\nEvery resource exposes `updated_at` and accepts `updated_from` / `updated_to`, so an integration can fetch only what changed since its last run. `GET /deleted` lists records that were removed from any resource, so your copy never keeps stale rows. Related resources (everything beyond the core records) page by ID rather than creation time; follow `next_cursor` the same way.\n\n## Writes and idempotency\n\nWrites that create or change business records require an `Idempotency-Key` header (each endpoint lists its headers). Retrying with the same key and exactly the same body returns the original result instead of creating a duplicate; reusing a key with a different body returns `409`. If an outcome is uncertain, look it up with the matching receipt endpoint rather than retrying under a new key.\n\n## Errors\n\n| Status | Meaning |\n| --- | --- |\n| `400` | Invalid or unsupported parameters |\n| `401` | Missing, invalid, expired or revoked API key |\n| `403` | The key does not have the required scope or company access |\n| `404` | Record not found in your organization |\n| `409` | Idempotency key reused with a different body, or the record changed since you read it |\n| `422` | The request was understood but the data is invalid |\n| `429` | Rate limit exceeded |\n| `5xx` | Temporary failure — retry the same request with the same idempotency key |\n\nError bodies look like `{ \"error\": \"Insufficient scope\", \"required_scope\": \"read:jobs\" }`.\n\n## Rate limits\n\nEach API key may make **120 requests per minute**. Requests over the limit receive `429`; wait and retry.\n\n## Permissions & safety\n\nEvery endpoint lists the permission (scope) it needs. Read scopes look like `read:jobs`; `read:details` adds full records with line items, and `read:activity` adds authored notes. Your complete history has its own read scopes: `read:communications` (calls, texts, emails, chats and the full timeline), `read:transcripts` (call transcripts and AI summaries), `read:field_records` (visit form answers, crew, inspection reports, signoffs, bait stations and traps), `read:payroll` (commissions and time entries), `read:complaints` and `read:bookings`. Each write action has its own `write:` scope, and none are granted automatically — an existing key never gains new permissions.\n\n- **Company access.** A key can cover the whole organization or selected companies. Filters can narrow what you see, never widen it. Some actions need a key with access to every company.\n- **Same rules as the office.** Writes go through the same workflows your team uses. The API never charges cards, issues refunds, accepts quotes for a customer or completes field work.\n- **Review first.** Actions that change existing records ask for the `updated_at` (or revision) you last read. If the record changed since, you get `409` — read it again before retrying.\n\n## Webhooks\n\nWildPipe pushes signed events to your server as records change — more than 100 event types covering customers, properties, leads, jobs, recurring plans, visits, quotes, invoices, payments, credits, agreements, warranties, notes, files, treatments, communications, referrals and deletions. Manage endpoints from **Settings → Webhooks** or entirely through this API (`/webhook-endpoints`, `/webhook-deliveries`, `/webhook-events`) with the `read:webhooks` and `write:webhooks` scopes. Every event type and its payload is documented under **x-webhooks** in this specification. WildPipe can also receive signed contact and lead webhooks from other systems. See [Guides & Webhooks](https://wildpipe.com/developers/api) for signature verification and recovery.\n\n## Testing safely\n\n**Try it** sends real requests to production. Use a key scoped to a test organization and test data — write requests create real records."},"tags":[{"name":"Customers","description":"Customer records, saved properties, identity, history and duplicate merges."},{"name":"Properties","description":"Saved service addresses linked to customers."},{"name":"Jobs","description":"Jobs (projects) for a customer, including phase, equipment, contacts and notes."},{"name":"Tasks & Visits","description":"Scheduled visits and field work, including instructions, completion and approvals."},{"name":"Appointments","description":"Book customer appointments into live availability."},{"name":"Availability","description":"Live bookable openings for a company and service."},{"name":"Booking Holds","description":"Temporarily reserve an opening before booking it."},{"name":"Quotes","description":"Estimates and proposals, revisions, declines and conversion to invoices."},{"name":"Invoices","description":"Invoices, balances and their status."},{"name":"Payments","description":"Recorded payments and allocations to invoices."},{"name":"Leads","description":"Sales leads, stages, loss reasons and conversions."},{"name":"Services","description":"Your service catalog and its variants."},{"name":"Products","description":"Your product catalog and its variants."},{"name":"Companies","description":"The brands (companies) in your organization."},{"name":"Employees","description":"Team members and technician routes."},{"name":"Documents","description":"Private customer document metadata and short-lived downloads."},{"name":"Email","description":"Send a customer email through your company sender."},{"name":"SMS","description":"Send a consent-aware customer text message."},{"name":"Communications","description":"Call, text, email and chat history, the full activity timeline, and call transcripts and summaries."},{"name":"Field & Compliance","description":"Visit form answers, crew assignments, inspection reports, work signoffs, warranty items, bait stations and traps."},{"name":"Payroll","description":"Commission ledger and time entries."},{"name":"Customer Concerns","description":"Customer concerns and their status."},{"name":"Online Bookings","description":"Booking requests submitted through your website booking widgets."},{"name":"Property Accounts","description":"Property manager accounts with their buildings, units, team, tenants and service requests."},{"name":"Plan Pricing","description":"Recurring plan price increases and renewal reminders."},{"name":"Activity Monitoring","description":"Monitored spots, pest and animal activity, corrective actions and saved monitoring reports."},{"name":"Outbound Webhooks","description":"Manage the endpoints WildPipe sends signed events to, review delivery history, replay failures and list every event type."},{"name":"Inbound Webhooks","description":"Create signed endpoints that receive contacts and leads from other systems."},{"name":"Sync & Deletions","description":"Records deleted since your last sync."},{"name":"Receipts","description":"Look up the committed result of an earlier write."},{"name":"Agreements"},{"name":"Automations"},{"name":"Booking Widgets"},{"name":"Business Settings"},{"name":"Cameras"},{"name":"Campaigns"},{"name":"Card Expiry Notices"},{"name":"Chat Widgets"},{"name":"Collections"},{"name":"Contractor Work Orders"},{"name":"Contractors"},{"name":"Credits"},{"name":"Disputes"},{"name":"Expenses"},{"name":"Forms"},{"name":"Reimbursements"},{"name":"Schedules"},{"name":"Service Report Settings"},{"name":"Subscriptions"},{"name":"Tags"},{"name":"Task Types"},{"name":"Time Off Requests"},{"name":"Treatment Products"},{"name":"Treatments"},{"name":"Warranties"}],"x-webhooks":{"contact.created":{"post":{"operationId":"webhook_contact_created","summary":"A customer record was created.","tags":["Outbound Webhooks"],"description":"A customer record was created. Subscribing through the API requires read:contacts. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["contact.created"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"first_name":{},"last_name":{},"email":{},"phone":{},"created_at":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"contact.updated":{"post":{"operationId":"webhook_contact_updated","summary":"A customer's name, email, phone or company changed.","tags":["Outbound Webhooks"],"description":"A customer's name, email, phone or company changed. Subscribing through the API requires read:contacts. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["contact.updated"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"first_name":{},"last_name":{},"email":{},"phone":{},"created_at":{},"company_id":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"contact.merged":{"post":{"operationId":"webhook_contact_merged","summary":"Duplicate customers were merged into this customer. The merged records are also sent as contact.deleted.","tags":["Outbound Webhooks"],"description":"Duplicate customers were merged into this customer. The merged records are also sent as contact.deleted. Subscribing through the API requires read:contacts. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["contact.merged"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"contact_id":{},"company_id":{},"merge_id":{},"merged_count":{},"merged_contact_ids":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"contact.tag_added":{"post":{"operationId":"webhook_contact_tag_added","summary":"A tag was added directly to a customer.","tags":["Outbound Webhooks"],"description":"A tag was added directly to a customer. Subscribing through the API requires read:contacts. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["contact.tag_added"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"contact_id":{},"tag_id":{},"company_id":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"contact.tag_removed":{"post":{"operationId":"webhook_contact_tag_removed","summary":"A direct tag was removed from a customer.","tags":["Outbound Webhooks"],"description":"A direct tag was removed from a customer. Subscribing through the API requires read:contacts. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["contact.tag_removed"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"contact_id":{},"tag_id":{},"company_id":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"contact.deleted":{"post":{"operationId":"webhook_contact_deleted","summary":"A customer record was deleted, including duplicates removed by a merge.","tags":["Outbound Webhooks"],"description":"A customer record was deleted, including duplicates removed by a merge. Subscribing through the API requires read:contacts. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["contact.deleted"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"deleted_at":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"property.created":{"post":{"operationId":"webhook_property_created","summary":"A service or billing property was saved for a customer.","tags":["Outbound Webhooks"],"description":"A service or billing property was saved for a customer. Subscribing through the API requires read:properties. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["property.created"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"contact_id":{},"company_id":{},"address":{},"address_line2":{},"is_primary_service":{},"is_primary_billing":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"property.updated":{"post":{"operationId":"webhook_property_updated","summary":"A saved property's address or primary flags changed.","tags":["Outbound Webhooks"],"description":"A saved property's address or primary flags changed. Subscribing through the API requires read:properties. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["property.updated"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"contact_id":{},"company_id":{},"address":{},"address_line2":{},"is_primary_service":{},"is_primary_billing":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"property.deleted":{"post":{"operationId":"webhook_property_deleted","summary":"A saved property was removed.","tags":["Outbound Webhooks"],"description":"A saved property was removed. Subscribing through the API requires read:properties. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["property.deleted"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"contact_id":{},"company_id":{},"address":{},"address_line2":{},"is_primary_service":{},"is_primary_billing":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"lead.created":{"post":{"operationId":"webhook_lead_created","summary":"A lead was created.","tags":["Outbound Webhooks"],"description":"A lead was created. Subscribing through the API requires read:leads. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["lead.created"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"contact_id":{},"company_id":{},"source":{},"status":{},"created_at":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"lead.status_changed":{"post":{"operationId":"webhook_lead_status_changed","summary":"A lead moved to a different stage.","tags":["Outbound Webhooks"],"description":"A lead moved to a different stage. Subscribing through the API requires read:leads. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["lead.status_changed"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"contact_id":{},"company_id":{},"source":{},"status":{},"created_at":{},"previous_status":{},"job_id":{},"quote_id":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"lead.converted":{"post":{"operationId":"webhook_lead_converted","summary":"A lead was marked won. This does not by itself mean work was booked or paid.","tags":["Outbound Webhooks"],"description":"A lead was marked won. This does not by itself mean work was booked or paid. Subscribing through the API requires read:leads. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["lead.converted"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"contact_id":{},"company_id":{},"source":{},"status":{},"created_at":{},"previous_status":{},"job_id":{},"quote_id":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"lead.deleted":{"post":{"operationId":"webhook_lead_deleted","summary":"A lead was deleted.","tags":["Outbound Webhooks"],"description":"A lead was deleted. Subscribing through the API requires read:leads. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["lead.deleted"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"deleted_at":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"job.created":{"post":{"operationId":"webhook_job_created","summary":"A job (project) was created.","tags":["Outbound Webhooks"],"description":"A job (project) was created. Subscribing through the API requires read:jobs. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["job.created"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"contact_id":{},"booking_number":{},"status":{},"phase":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"job.updated":{"post":{"operationId":"webhook_job_updated","summary":"A job's company, customer, booking number, status or phase changed.","tags":["Outbound Webhooks"],"description":"A job's company, customer, booking number, status or phase changed. Subscribing through the API requires read:jobs. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["job.updated"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"contact_id":{},"booking_number":{},"status":{},"phase":{},"previous_status":{},"previous_phase":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"job.phase_changed":{"post":{"operationId":"webhook_job_phase_changed","summary":"A job moved to a different work phase.","tags":["Outbound Webhooks"],"description":"A job moved to a different work phase. Subscribing through the API requires read:jobs. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["job.phase_changed"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"contact_id":{},"booking_number":{},"status":{},"phase":{},"previous_status":{},"previous_phase":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"job.completed":{"post":{"operationId":"webhook_job_completed","summary":"A job was completed.","tags":["Outbound Webhooks"],"description":"A job was completed. Subscribing through the API requires read:jobs. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["job.completed"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"contact_id":{},"booking_number":{},"status":{},"phase":{},"previous_status":{},"previous_phase":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"job.cancelled":{"post":{"operationId":"webhook_job_cancelled","summary":"A job was cancelled.","tags":["Outbound Webhooks"],"description":"A job was cancelled. Subscribing through the API requires read:jobs. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["job.cancelled"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"contact_id":{},"booking_number":{},"status":{},"phase":{},"previous_status":{},"previous_phase":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"job.tag_added":{"post":{"operationId":"webhook_job_tag_added","summary":"A tag was added to a job.","tags":["Outbound Webhooks"],"description":"A tag was added to a job. Subscribing through the API requires read:jobs. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["job.tag_added"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"job_id":{},"tag_id":{},"company_id":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"job.tag_removed":{"post":{"operationId":"webhook_job_tag_removed","summary":"A tag was removed from a job.","tags":["Outbound Webhooks"],"description":"A tag was removed from a job. Subscribing through the API requires read:jobs. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["job.tag_removed"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"job_id":{},"tag_id":{},"company_id":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"job.deleted":{"post":{"operationId":"webhook_job_deleted","summary":"A job was deleted.","tags":["Outbound Webhooks"],"description":"A job was deleted. Subscribing through the API requires read:jobs. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["job.deleted"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"deleted_at":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"service_plan.enrolled":{"post":{"operationId":"webhook_service_plan_enrolled","summary":"A job became a recurring service plan.","tags":["Outbound Webhooks"],"description":"A job became a recurring service plan. Subscribing through the API requires read:jobs. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["service_plan.enrolled"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"job_id":{},"company_id":{},"contact_id":{},"subscription_status":{},"previous_subscription_status":{},"recurrence_interval":{},"billing_frequency":{},"next_service_date":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"service_plan.paused":{"post":{"operationId":"webhook_service_plan_paused","summary":"A recurring plan was paused.","tags":["Outbound Webhooks"],"description":"A recurring plan was paused. Subscribing through the API requires read:jobs. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["service_plan.paused"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"job_id":{},"company_id":{},"contact_id":{},"subscription_status":{},"previous_subscription_status":{},"recurrence_interval":{},"billing_frequency":{},"next_service_date":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"service_plan.resumed":{"post":{"operationId":"webhook_service_plan_resumed","summary":"A paused or past-due plan became active again.","tags":["Outbound Webhooks"],"description":"A paused or past-due plan became active again. Subscribing through the API requires read:jobs. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["service_plan.resumed"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"job_id":{},"company_id":{},"contact_id":{},"subscription_status":{},"previous_subscription_status":{},"recurrence_interval":{},"billing_frequency":{},"next_service_date":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"service_plan.past_due":{"post":{"operationId":"webhook_service_plan_past_due","summary":"A recurring plan was suspended for unpaid charges.","tags":["Outbound Webhooks"],"description":"A recurring plan was suspended for unpaid charges. Subscribing through the API requires read:jobs. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["service_plan.past_due"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"job_id":{},"company_id":{},"contact_id":{},"subscription_status":{},"previous_subscription_status":{},"recurrence_interval":{},"billing_frequency":{},"next_service_date":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"service_plan.cancelled":{"post":{"operationId":"webhook_service_plan_cancelled","summary":"A recurring plan was cancelled.","tags":["Outbound Webhooks"],"description":"A recurring plan was cancelled. Subscribing through the API requires read:jobs. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["service_plan.cancelled"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"job_id":{},"company_id":{},"contact_id":{},"subscription_status":{},"previous_subscription_status":{},"recurrence_interval":{},"billing_frequency":{},"next_service_date":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"task.created":{"post":{"operationId":"webhook_task_created","summary":"A visit or task was created.","tags":["Outbound Webhooks"],"description":"A visit or task was created. Subscribing through the API requires read:tasks. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["task.created"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"job_id":{},"contact_id":{},"parent_task_id":{},"status_id":{},"previous_status_id":{},"assigned_to":{},"previous_assigned_to":{},"completed_time":{},"is_appointment":{},"is_all_day":{},"arrive_by":{},"start_time":{},"end_time":{},"arrival_window_start":{},"arrival_window_end":{},"access_window_start":{},"access_window_end":{},"complete_by":{},"due_at":{},"is_multi_day":{},"project_start_date":{},"project_end_date":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"task.assigned":{"post":{"operationId":"webhook_task_assigned","summary":"A visit was assigned to a technician or moved to a different one.","tags":["Outbound Webhooks"],"description":"A visit was assigned to a technician or moved to a different one. Subscribing through the API requires read:tasks. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["task.assigned"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"job_id":{},"contact_id":{},"parent_task_id":{},"status_id":{},"previous_status_id":{},"assigned_to":{},"previous_assigned_to":{},"completed_time":{},"is_appointment":{},"is_all_day":{},"arrive_by":{},"start_time":{},"end_time":{},"arrival_window_start":{},"arrival_window_end":{},"access_window_start":{},"access_window_end":{},"complete_by":{},"due_at":{},"is_multi_day":{},"project_start_date":{},"project_end_date":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"task.unassigned":{"post":{"operationId":"webhook_task_unassigned","summary":"A visit's technician was removed.","tags":["Outbound Webhooks"],"description":"A visit's technician was removed. Subscribing through the API requires read:tasks. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["task.unassigned"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"job_id":{},"contact_id":{},"parent_task_id":{},"status_id":{},"previous_status_id":{},"assigned_to":{},"previous_assigned_to":{},"completed_time":{},"is_appointment":{},"is_all_day":{},"arrive_by":{},"start_time":{},"end_time":{},"arrival_window_start":{},"arrival_window_end":{},"access_window_start":{},"access_window_end":{},"complete_by":{},"due_at":{},"is_multi_day":{},"project_start_date":{},"project_end_date":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"task.rescheduled":{"post":{"operationId":"webhook_task_rescheduled","summary":"A visit's scheduled timing, arrival window, arrive-by time, access window or deadline changed. Route order and arrival estimate changes do not send it.","tags":["Outbound Webhooks"],"description":"A visit's scheduled timing, arrival window, arrive-by time, access window or deadline changed. Route order and arrival estimate changes do not send it. Subscribing through the API requires read:tasks. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["task.rescheduled"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"job_id":{},"contact_id":{},"parent_task_id":{},"status_id":{},"previous_status_id":{},"assigned_to":{},"previous_assigned_to":{},"completed_time":{},"is_appointment":{},"is_all_day":{},"arrive_by":{},"start_time":{},"end_time":{},"arrival_window_start":{},"arrival_window_end":{},"access_window_start":{},"access_window_end":{},"complete_by":{},"due_at":{},"is_multi_day":{},"project_start_date":{},"project_end_date":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"task.status_changed":{"post":{"operationId":"webhook_task_status_changed","summary":"A visit changed status.","tags":["Outbound Webhooks"],"description":"A visit changed status. Subscribing through the API requires read:tasks. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["task.status_changed"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"job_id":{},"contact_id":{},"parent_task_id":{},"status_id":{},"previous_status_id":{},"assigned_to":{},"previous_assigned_to":{},"completed_time":{},"is_appointment":{},"is_all_day":{},"arrive_by":{},"start_time":{},"end_time":{},"arrival_window_start":{},"arrival_window_end":{},"access_window_start":{},"access_window_end":{},"complete_by":{},"due_at":{},"is_multi_day":{},"project_start_date":{},"project_end_date":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"task.submitted_for_approval":{"post":{"operationId":"webhook_task_submitted_for_approval","summary":"A technician submitted a visit that needs supervisor approval.","tags":["Outbound Webhooks"],"description":"A technician submitted a visit that needs supervisor approval. Subscribing through the API requires read:tasks. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["task.submitted_for_approval"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"job_id":{},"contact_id":{},"parent_task_id":{},"status_id":{},"previous_status_id":{},"assigned_to":{},"previous_assigned_to":{},"completed_time":{},"is_appointment":{},"is_all_day":{},"arrive_by":{},"start_time":{},"end_time":{},"arrival_window_start":{},"arrival_window_end":{},"access_window_start":{},"access_window_end":{},"complete_by":{},"due_at":{},"is_multi_day":{},"project_start_date":{},"project_end_date":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"task.completed":{"post":{"operationId":"webhook_task_completed","summary":"A visit was completed (and approved, when approval is required).","tags":["Outbound Webhooks"],"description":"A visit was completed (and approved, when approval is required). Subscribing through the API requires read:tasks. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["task.completed"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"job_id":{},"contact_id":{},"parent_task_id":{},"status_id":{},"previous_status_id":{},"assigned_to":{},"previous_assigned_to":{},"completed_time":{},"is_appointment":{},"is_all_day":{},"arrive_by":{},"start_time":{},"end_time":{},"arrival_window_start":{},"arrival_window_end":{},"access_window_start":{},"access_window_end":{},"complete_by":{},"due_at":{},"is_multi_day":{},"project_start_date":{},"project_end_date":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"task.rejected":{"post":{"operationId":"webhook_task_rejected","summary":"A submitted visit was sent back for redo.","tags":["Outbound Webhooks"],"description":"A submitted visit was sent back for redo. Subscribing through the API requires read:tasks. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["task.rejected"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"job_id":{},"contact_id":{},"parent_task_id":{},"status_id":{},"previous_status_id":{},"assigned_to":{},"previous_assigned_to":{},"completed_time":{},"is_appointment":{},"is_all_day":{},"arrive_by":{},"start_time":{},"end_time":{},"arrival_window_start":{},"arrival_window_end":{},"access_window_start":{},"access_window_end":{},"complete_by":{},"due_at":{},"is_multi_day":{},"project_start_date":{},"project_end_date":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"task.failed":{"post":{"operationId":"webhook_task_failed","summary":"A visit was marked failed.","tags":["Outbound Webhooks"],"description":"A visit was marked failed. Subscribing through the API requires read:tasks. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["task.failed"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"job_id":{},"contact_id":{},"parent_task_id":{},"status_id":{},"previous_status_id":{},"assigned_to":{},"previous_assigned_to":{},"completed_time":{},"is_appointment":{},"is_all_day":{},"arrive_by":{},"start_time":{},"end_time":{},"arrival_window_start":{},"arrival_window_end":{},"access_window_start":{},"access_window_end":{},"complete_by":{},"due_at":{},"is_multi_day":{},"project_start_date":{},"project_end_date":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"task.cancelled":{"post":{"operationId":"webhook_task_cancelled","summary":"A visit was cancelled.","tags":["Outbound Webhooks"],"description":"A visit was cancelled. Subscribing through the API requires read:tasks. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["task.cancelled"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"job_id":{},"contact_id":{},"parent_task_id":{},"status_id":{},"previous_status_id":{},"assigned_to":{},"previous_assigned_to":{},"completed_time":{},"is_appointment":{},"is_all_day":{},"arrive_by":{},"start_time":{},"end_time":{},"arrival_window_start":{},"arrival_window_end":{},"access_window_start":{},"access_window_end":{},"complete_by":{},"due_at":{},"is_multi_day":{},"project_start_date":{},"project_end_date":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"task.deleted":{"post":{"operationId":"webhook_task_deleted","summary":"A visit was deleted.","tags":["Outbound Webhooks"],"description":"A visit was deleted. Subscribing through the API requires read:tasks. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["task.deleted"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"deleted_at":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"quote.created":{"post":{"operationId":"webhook_quote_created","summary":"A quote was created.","tags":["Outbound Webhooks"],"description":"A quote was created. Subscribing through the API requires read:quotes. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["quote.created"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"contact_id":{},"job_id":{},"quote_number":{},"status":{},"previous_status":{},"total":{},"version":{},"accepted_at":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"quote.sent":{"post":{"operationId":"webhook_quote_sent","summary":"A quote was marked sent.","tags":["Outbound Webhooks"],"description":"A quote was marked sent. Subscribing through the API requires read:quotes. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["quote.sent"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"contact_id":{},"job_id":{},"quote_number":{},"status":{},"previous_status":{},"total":{},"version":{},"accepted_at":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"quote.accepted":{"post":{"operationId":"webhook_quote_accepted","summary":"A quote was accepted by the customer or on their behalf.","tags":["Outbound Webhooks"],"description":"A quote was accepted by the customer or on their behalf. Subscribing through the API requires read:quotes. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["quote.accepted"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"contact_id":{},"job_id":{},"quote_number":{},"status":{},"previous_status":{},"total":{},"version":{},"accepted_at":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"quote.declined":{"post":{"operationId":"webhook_quote_declined","summary":"A quote was declined.","tags":["Outbound Webhooks"],"description":"A quote was declined. Subscribing through the API requires read:quotes. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["quote.declined"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"contact_id":{},"job_id":{},"quote_number":{},"status":{},"previous_status":{},"total":{},"version":{},"accepted_at":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"quote.status_changed":{"post":{"operationId":"webhook_quote_status_changed","summary":"A quote changed status, including revisions, cancellations and invoicing.","tags":["Outbound Webhooks"],"description":"A quote changed status, including revisions, cancellations and invoicing. Subscribing through the API requires read:quotes. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["quote.status_changed"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"contact_id":{},"job_id":{},"quote_number":{},"status":{},"previous_status":{},"total":{},"version":{},"accepted_at":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"quote.deleted":{"post":{"operationId":"webhook_quote_deleted","summary":"A quote was deleted.","tags":["Outbound Webhooks"],"description":"A quote was deleted. Subscribing through the API requires read:quotes. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["quote.deleted"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"deleted_at":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"invoice.created":{"post":{"operationId":"webhook_invoice_created","summary":"An invoice was created.","tags":["Outbound Webhooks"],"description":"An invoice was created. Subscribing through the API requires read:invoices. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["invoice.created"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"contact_id":{},"job_id":{},"quote_id":{},"invoice_number":{},"status":{},"previous_status":{},"total":{},"amount_paid":{},"due_date":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"invoice.sent":{"post":{"operationId":"webhook_invoice_sent","summary":"An invoice was marked sent.","tags":["Outbound Webhooks"],"description":"An invoice was marked sent. Subscribing through the API requires read:invoices. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["invoice.sent"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"contact_id":{},"job_id":{},"quote_id":{},"invoice_number":{},"status":{},"previous_status":{},"total":{},"amount_paid":{},"due_date":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"invoice.updated":{"post":{"operationId":"webhook_invoice_updated","summary":"An invoice's total or due date changed.","tags":["Outbound Webhooks"],"description":"An invoice's total or due date changed. Subscribing through the API requires read:invoices. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["invoice.updated"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"contact_id":{},"job_id":{},"quote_id":{},"invoice_number":{},"status":{},"previous_status":{},"total":{},"amount_paid":{},"due_date":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"invoice.paid":{"post":{"operationId":"webhook_invoice_paid","summary":"An invoice became fully paid.","tags":["Outbound Webhooks"],"description":"An invoice became fully paid. Subscribing through the API requires read:invoices. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["invoice.paid"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"contact_id":{},"job_id":{},"quote_id":{},"invoice_number":{},"status":{},"previous_status":{},"total":{},"amount_paid":{},"due_date":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"invoice.voided":{"post":{"operationId":"webhook_invoice_voided","summary":"An invoice was voided.","tags":["Outbound Webhooks"],"description":"An invoice was voided. Subscribing through the API requires read:invoices. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["invoice.voided"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"contact_id":{},"job_id":{},"quote_id":{},"invoice_number":{},"status":{},"previous_status":{},"total":{},"amount_paid":{},"due_date":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"invoice.status_changed":{"post":{"operationId":"webhook_invoice_status_changed","summary":"An invoice changed status, including reversals back to unpaid.","tags":["Outbound Webhooks"],"description":"An invoice changed status, including reversals back to unpaid. Subscribing through the API requires read:invoices. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["invoice.status_changed"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"contact_id":{},"job_id":{},"quote_id":{},"invoice_number":{},"status":{},"previous_status":{},"total":{},"amount_paid":{},"due_date":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"invoice.deleted":{"post":{"operationId":"webhook_invoice_deleted","summary":"An invoice was deleted.","tags":["Outbound Webhooks"],"description":"An invoice was deleted. Subscribing through the API requires read:invoices. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["invoice.deleted"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"deleted_at":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"payment.received":{"post":{"operationId":"webhook_payment_received","summary":"A payment record became successful. Reconcile by payment_id; a reversal returning to successful is not new money.","tags":["Outbound Webhooks"],"description":"A payment record became successful. Reconcile by payment_id; a reversal returning to successful is not new money. Subscribing through the API requires read:payments. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["payment.received"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"payment_id":{},"company_id":{},"contact_id":{},"quote_id":{},"amount":{},"base_amount":{},"tip_amount":{},"method":{},"status":{},"previous_status":{},"created_at":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"payment.failed":{"post":{"operationId":"webhook_payment_failed","summary":"A payment record failed.","tags":["Outbound Webhooks"],"description":"A payment record failed. Subscribing through the API requires read:payments. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["payment.failed"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"payment_id":{},"company_id":{},"contact_id":{},"quote_id":{},"amount":{},"base_amount":{},"tip_amount":{},"method":{},"status":{},"previous_status":{},"created_at":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"payment.status_changed":{"post":{"operationId":"webhook_payment_status_changed","summary":"A payment changed status, including disputes and reversals.","tags":["Outbound Webhooks"],"description":"A payment changed status, including disputes and reversals. Subscribing through the API requires read:payments. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["payment.status_changed"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"payment_id":{},"company_id":{},"contact_id":{},"quote_id":{},"amount":{},"base_amount":{},"tip_amount":{},"method":{},"status":{},"previous_status":{},"created_at":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"payment.allocated":{"post":{"operationId":"webhook_payment_allocated","summary":"Money from a payment was applied to an invoice, or the applied amount changed.","tags":["Outbound Webhooks"],"description":"Money from a payment was applied to an invoice, or the applied amount changed. Subscribing through the API requires read:payments. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["payment.allocated"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"payment_id":{},"invoice_id":{},"company_id":{},"contact_id":{},"amount_allocated":{},"previous_amount_allocated":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"payment.allocation_removed":{"post":{"operationId":"webhook_payment_allocation_removed","summary":"Money was un-applied from an invoice.","tags":["Outbound Webhooks"],"description":"Money was un-applied from an invoice. Subscribing through the API requires read:payments. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["payment.allocation_removed"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"payment_id":{},"invoice_id":{},"company_id":{},"contact_id":{},"amount_allocated":{},"previous_amount_allocated":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"payment.deleted":{"post":{"operationId":"webhook_payment_deleted","summary":"A payment record was deleted.","tags":["Outbound Webhooks"],"description":"A payment record was deleted. Subscribing through the API requires read:payments. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["payment.deleted"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"deleted_at":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"credit.issued":{"post":{"operationId":"webhook_credit_issued","summary":"A customer credit was issued. Credit is not collected revenue.","tags":["Outbound Webhooks"],"description":"A customer credit was issued. Credit is not collected revenue. Subscribing through the API requires read:credits. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["credit.issued"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"contact_id":{},"invoice_id":{},"credit_number":{},"amount":{},"remaining_balance":{},"status":{},"previous_status":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"credit.status_changed":{"post":{"operationId":"webhook_credit_status_changed","summary":"A customer credit changed status.","tags":["Outbound Webhooks"],"description":"A customer credit changed status. Subscribing through the API requires read:credits. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["credit.status_changed"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"contact_id":{},"invoice_id":{},"credit_number":{},"amount":{},"remaining_balance":{},"status":{},"previous_status":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"agreement.created":{"post":{"operationId":"webhook_agreement_created","summary":"A service agreement was created.","tags":["Outbound Webhooks"],"description":"A service agreement was created. Subscribing through the API requires read:agreements. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["agreement.created"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"job_id":{},"contact_id":{},"status":{},"previous_status":{},"service_name":{},"term_months":{},"start_date":{},"end_date":{},"recurring_price":{},"billing_frequency":{},"signed_at":{},"cancelled_at":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"agreement.signed":{"post":{"operationId":"webhook_agreement_signed","summary":"A service agreement was signed.","tags":["Outbound Webhooks"],"description":"A service agreement was signed. Subscribing through the API requires read:agreements. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["agreement.signed"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"job_id":{},"contact_id":{},"status":{},"previous_status":{},"service_name":{},"term_months":{},"start_date":{},"end_date":{},"recurring_price":{},"billing_frequency":{},"signed_at":{},"cancelled_at":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"agreement.cancelled":{"post":{"operationId":"webhook_agreement_cancelled","summary":"A service agreement was cancelled.","tags":["Outbound Webhooks"],"description":"A service agreement was cancelled. Subscribing through the API requires read:agreements. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["agreement.cancelled"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"job_id":{},"contact_id":{},"status":{},"previous_status":{},"service_name":{},"term_months":{},"start_date":{},"end_date":{},"recurring_price":{},"billing_frequency":{},"signed_at":{},"cancelled_at":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"agreement.status_changed":{"post":{"operationId":"webhook_agreement_status_changed","summary":"A service agreement changed status.","tags":["Outbound Webhooks"],"description":"A service agreement changed status. Subscribing through the API requires read:agreements. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["agreement.status_changed"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"job_id":{},"contact_id":{},"status":{},"previous_status":{},"service_name":{},"term_months":{},"start_date":{},"end_date":{},"recurring_price":{},"billing_frequency":{},"signed_at":{},"cancelled_at":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"warranty.created":{"post":{"operationId":"webhook_warranty_created","summary":"A warranty was created.","tags":["Outbound Webhooks"],"description":"A warranty was created. Subscribing through the API requires read:warranties. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["warranty.created"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"job_id":{},"invoice_id":{},"contact_id":{},"warranty_type":{},"status":{},"previous_status":{},"start_date":{},"end_date":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"warranty.status_changed":{"post":{"operationId":"webhook_warranty_status_changed","summary":"A warranty changed status.","tags":["Outbound Webhooks"],"description":"A warranty changed status. Subscribing through the API requires read:warranties. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["warranty.status_changed"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"job_id":{},"invoice_id":{},"contact_id":{},"warranty_type":{},"status":{},"previous_status":{},"start_date":{},"end_date":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"note.created":{"post":{"operationId":"webhook_note_created","summary":"A note was added to a customer or job. Note text is not included; read it through the API.","tags":["Outbound Webhooks"],"description":"A note was added to a customer or job. Note text is not included; read it through the API. Subscribing through the API requires read:activity. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["note.created"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"contact_id":{},"job_id":{},"task_id":{},"company_id":{},"visibility":{},"created_at":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"document.created":{"post":{"operationId":"webhook_document_created","summary":"A customer file was added. File contents are never included.","tags":["Outbound Webhooks"],"description":"A customer file was added. File contents are never included. Subscribing through the API requires read:documents. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["document.created"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"contact_id":{},"job_id":{},"quote_id":{},"invoice_id":{},"warranty_id":{},"agreement_id":{},"category":{},"file_name":{},"mime_type":{},"size_bytes":{},"visibility":{},"created_at":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"document.archived":{"post":{"operationId":"webhook_document_archived","summary":"A customer file was archived.","tags":["Outbound Webhooks"],"description":"A customer file was archived. Subscribing through the API requires read:documents. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["document.archived"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"contact_id":{},"job_id":{},"quote_id":{},"invoice_id":{},"warranty_id":{},"agreement_id":{},"category":{},"file_name":{},"mime_type":{},"size_bytes":{},"visibility":{},"created_at":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"document.deleted":{"post":{"operationId":"webhook_document_deleted","summary":"A customer file was deleted.","tags":["Outbound Webhooks"],"description":"A customer file was deleted. Subscribing through the API requires read:documents. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["document.deleted"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"contact_id":{},"job_id":{},"quote_id":{},"invoice_id":{},"warranty_id":{},"agreement_id":{},"category":{},"file_name":{},"mime_type":{},"size_bytes":{},"visibility":{},"created_at":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"trap.created":{"post":{"operationId":"webhook_trap_created","summary":"A trap was added to inventory.","tags":["Outbound Webhooks"],"description":"A trap was added to inventory. Subscribing through the API requires read:field_records. Organization-wide: company-restricted endpoints do not receive it. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["trap.created"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"label":{},"trap_type":{},"serial_number":{},"status":{},"previous_status":{},"target_species":{},"updated_at":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"trap.updated":{"post":{"operationId":"webhook_trap_updated","summary":"A trap's label, type, serial number, target species, notes or check frequency changed.","tags":["Outbound Webhooks"],"description":"A trap's label, type, serial number, target species, notes or check frequency changed. Subscribing through the API requires read:field_records. Organization-wide: company-restricted endpoints do not receive it. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["trap.updated"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"label":{},"trap_type":{},"serial_number":{},"status":{},"previous_status":{},"target_species":{},"updated_at":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"trap.status_changed":{"post":{"operationId":"webhook_trap_status_changed","summary":"A trap changed status (available, on a truck, deployed, needs service or retired).","tags":["Outbound Webhooks"],"description":"A trap changed status (available, on a truck, deployed, needs service or retired). Subscribing through the API requires read:field_records. Organization-wide: company-restricted endpoints do not receive it. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["trap.status_changed"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"label":{},"trap_type":{},"serial_number":{},"status":{},"previous_status":{},"target_species":{},"updated_at":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"camera.created":{"post":{"operationId":"webhook_camera_created","summary":"A camera was added.","tags":["Outbound Webhooks"],"description":"A camera was added. Subscribing through the API requires read:equipment. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["camera.created"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"contact_id":{},"booking_number":{},"status":{},"previous_status":{},"manufacturer":{},"model":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"camera.status_changed":{"post":{"operationId":"webhook_camera_status_changed","summary":"A camera changed status (active, on a truck or archived).","tags":["Outbound Webhooks"],"description":"A camera changed status (active, on a truck or archived). Subscribing through the API requires read:equipment. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["camera.status_changed"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"contact_id":{},"booking_number":{},"status":{},"previous_status":{},"manufacturer":{},"model":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"complaint.created":{"post":{"operationId":"webhook_complaint_created","summary":"A customer concern was recorded. Its summary is not included; read it through the API.","tags":["Outbound Webhooks"],"description":"A customer concern was recorded. Its summary is not included; read it through the API. Subscribing through the API requires read:complaints. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["complaint.created"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"contact_id":{},"job_id":{},"source":{},"status":{},"previous_status":{},"created_at":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"complaint.status_changed":{"post":{"operationId":"webhook_complaint_status_changed","summary":"A customer concern moved between open, addressing and resolved.","tags":["Outbound Webhooks"],"description":"A customer concern moved between open, addressing and resolved. Subscribing through the API requires read:complaints. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["complaint.status_changed"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"contact_id":{},"job_id":{},"source":{},"status":{},"previous_status":{},"created_at":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"corporate_request.created":{"post":{"operationId":"webhook_corporate_request_created","summary":"A service request was filed for a property account unit, by a tenant, a manager, the office or an AI assistant.","tags":["Outbound Webhooks"],"description":"A service request was filed for a property account unit, by a tenant, a manager, the office or an AI assistant. Subscribing through the API requires read:corporate_accounts. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["corporate_request.created"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"account_id":{},"unit_id":{},"tenant_contact_id":{},"service_id":{},"status":{},"previous_status":{},"payer":{},"source":{},"job_id":{},"created_at":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"corporate_request.status_changed":{"post":{"operationId":"webhook_corporate_request_status_changed","summary":"A property account service request was approved, declined, scheduled or cancelled.","tags":["Outbound Webhooks"],"description":"A property account service request was approved, declined, scheduled or cancelled. Subscribing through the API requires read:corporate_accounts. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["corporate_request.status_changed"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"account_id":{},"unit_id":{},"tenant_contact_id":{},"service_id":{},"status":{},"previous_status":{},"payer":{},"source":{},"job_id":{},"created_at":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"corporate_tenant.moved_in":{"post":{"operationId":"webhook_corporate_tenant_moved_in","summary":"A tenant was added to a property account unit.","tags":["Outbound Webhooks"],"description":"A tenant was added to a property account unit. Subscribing through the API requires read:corporate_accounts. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["corporate_tenant.moved_in"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"account_id":{},"unit_id":{},"contact_id":{},"status":{},"move_in_date":{},"move_out_date":{},"end_reason":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"corporate_tenant.moved_out":{"post":{"operationId":"webhook_corporate_tenant_moved_out","summary":"A tenant's tenancy ended. The former tenant's record is kept.","tags":["Outbound Webhooks"],"description":"A tenant's tenancy ended. The former tenant's record is kept. Subscribing through the API requires read:corporate_accounts. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["corporate_tenant.moved_out"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"account_id":{},"unit_id":{},"contact_id":{},"status":{},"move_in_date":{},"move_out_date":{},"end_reason":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"treatment.logged":{"post":{"operationId":"webhook_treatment_logged","summary":"A pesticide application record was logged.","tags":["Outbound Webhooks"],"description":"A pesticide application record was logged. Subscribing through the API requires read:treatments. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["treatment.logged"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"job_id":{},"task_id":{},"treatment_id":{},"application_started_at":{},"application_ended_at":{},"target_pests":{},"restricted_entry_hours":{},"reentry_at":{},"customer_notified":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"activity.recorded":{"post":{"operationId":"webhook_activity_recorded","summary":"A pest or animal activity record was added (device check, sensor, camera check confirmed by a person, removal, sighting or finding). Corrections arrive as new records that name the record they replace. Notes and photos are not included.","tags":["Outbound Webhooks"],"description":"A pest or animal activity record was added (device check, sensor, camera check confirmed by a person, removal, sighting or finding). Corrections arrive as new records that name the record they replace. Notes and photos are not included. Subscribing through the API requires read:monitoring. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["activity.recorded"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"job_id":{},"contact_id":{},"point_id":{},"observation":{},"pest_group":{},"species":{},"quantity":{},"severity":{},"trust":{},"source_kind":{},"corrects_id":{},"customer_visible":{},"observed_at":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"monitoring_action.opened":{"post":{"operationId":"webhook_monitoring_action_opened","summary":"A corrective action was opened from activity or a finding.","tags":["Outbound Webhooks"],"description":"A corrective action was opened from activity or a finding. Subscribing through the API requires read:monitoring. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["monitoring_action.opened"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"job_id":{},"contact_id":{},"point_id":{},"observation_id":{},"category":{},"responsible":{},"priority":{},"status":{},"previous_status":{},"due_date":{},"completed_at":{},"verified_at":{},"customer_ack_at":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"monitoring_action.status_changed":{"post":{"operationId":"webhook_monitoring_action_status_changed","summary":"A corrective action moved between open, in progress, done, verified or cancelled.","tags":["Outbound Webhooks"],"description":"A corrective action moved between open, in progress, done, verified or cancelled. Subscribing through the API requires read:monitoring. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["monitoring_action.status_changed"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"job_id":{},"contact_id":{},"point_id":{},"observation_id":{},"category":{},"responsible":{},"priority":{},"status":{},"previous_status":{},"due_date":{},"completed_at":{},"verified_at":{},"customer_ack_at":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"monitoring_report.created":{"post":{"operationId":"webhook_monitoring_report_created","summary":"An activity report, audit packet or pest risk assessment was saved, by a person or on schedule.","tags":["Outbound Webhooks"],"description":"An activity report, audit packet or pest risk assessment was saved, by a person or on schedule. Subscribing through the API requires read:monitoring. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["monitoring_report.created"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"contact_id":{},"corporate_account_id":{},"report_kind":{},"scope_type":{},"scope_id":{},"standard":{},"period_start":{},"period_end":{},"customer_visible":{},"generated_via":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"pest_sighting.reported":{"post":{"operationId":"webhook_pest_sighting_reported","summary":"A pest sighting was reported.","tags":["Outbound Webhooks"],"description":"A pest sighting was reported. Subscribing through the API requires read:pest_sightings. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["pest_sighting.reported"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"job_id":{},"contact_id":{},"pest_type_id":{},"severity":{},"sighting_date":{},"created_at":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"sms.received":{"post":{"operationId":"webhook_sms_received","summary":"A customer text message arrived. Opt-out and help keywords are excluded. Message text is not included.","tags":["Outbound Webhooks"],"description":"A customer text message arrived. Opt-out and help keywords are excluded. Message text is not included. Subscribing through the API requires read:activity. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["sms.received"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"sms_id":{},"contact_id":{},"job_id":{},"direction":{},"status":{},"num_media":{},"num_segments":{},"created_at":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"sms.sent":{"post":{"operationId":"webhook_sms_sent","summary":"An outgoing text was handed to the carrier. This is not proof of delivery.","tags":["Outbound Webhooks"],"description":"An outgoing text was handed to the carrier. This is not proof of delivery. Subscribing through the API requires read:activity. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["sms.sent"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"sms_id":{},"contact_id":{},"job_id":{},"direction":{},"status":{},"num_media":{},"num_segments":{},"created_at":{},"error_code":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"sms.delivered":{"post":{"operationId":"webhook_sms_delivered","summary":"The carrier reported an outgoing text delivered.","tags":["Outbound Webhooks"],"description":"The carrier reported an outgoing text delivered. Subscribing through the API requires read:activity. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["sms.delivered"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"sms_id":{},"contact_id":{},"job_id":{},"direction":{},"status":{},"num_media":{},"num_segments":{},"created_at":{},"error_code":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"sms.failed":{"post":{"operationId":"webhook_sms_failed","summary":"An outgoing text failed or was undeliverable.","tags":["Outbound Webhooks"],"description":"An outgoing text failed or was undeliverable. Subscribing through the API requires read:activity. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["sms.failed"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"sms_id":{},"contact_id":{},"job_id":{},"direction":{},"status":{},"num_media":{},"num_segments":{},"created_at":{},"error_code":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"call.completed":{"post":{"operationId":"webhook_call_completed","summary":"A customer call finished.","tags":["Outbound Webhooks"],"description":"A customer call finished. Subscribing through the API requires read:activity. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["call.completed"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"call_id":{},"contact_id":{},"job_id":{},"company_id":{},"direction":{},"status":{},"duration":{},"created_at":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"call.missed":{"post":{"operationId":"webhook_call_missed","summary":"An incoming call was missed, unanswered or busy.","tags":["Outbound Webhooks"],"description":"An incoming call was missed, unanswered or busy. Subscribing through the API requires read:activity. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["call.missed"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"call_id":{},"contact_id":{},"job_id":{},"company_id":{},"direction":{},"status":{},"duration":{},"created_at":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"call.voicemail":{"post":{"operationId":"webhook_call_voicemail","summary":"An incoming call went to voicemail.","tags":["Outbound Webhooks"],"description":"An incoming call went to voicemail. Subscribing through the API requires read:activity. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["call.voicemail"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"call_id":{},"contact_id":{},"job_id":{},"company_id":{},"direction":{},"status":{},"duration":{},"created_at":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"email.sent":{"post":{"operationId":"webhook_email_sent","summary":"A company email to a customer was sent. Personal mailboxes are excluded. Email content is not included.","tags":["Outbound Webhooks"],"description":"A company email to a customer was sent. Personal mailboxes are excluded. Email content is not included. Subscribing through the API requires read:activity. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["email.sent"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"email_id":{},"company_id":{},"contact_id":{},"job_id":{},"quote_id":{},"invoice_id":{},"status":{},"created_at":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"email.delivered":{"post":{"operationId":"webhook_email_delivered","summary":"A company email was reported delivered.","tags":["Outbound Webhooks"],"description":"A company email was reported delivered. Subscribing through the API requires read:activity. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["email.delivered"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"email_id":{},"company_id":{},"contact_id":{},"job_id":{},"quote_id":{},"invoice_id":{},"status":{},"created_at":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"email.bounced":{"post":{"operationId":"webhook_email_bounced","summary":"A company email bounced.","tags":["Outbound Webhooks"],"description":"A company email bounced. Subscribing through the API requires read:activity. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["email.bounced"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"email_id":{},"company_id":{},"contact_id":{},"job_id":{},"quote_id":{},"invoice_id":{},"status":{},"created_at":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"email.received":{"post":{"operationId":"webhook_email_received","summary":"A non-spam email arrived at a company address. Personal mailboxes are excluded. Email content is not included.","tags":["Outbound Webhooks"],"description":"A non-spam email arrived at a company address. Personal mailboxes are excluded. Email content is not included. Subscribing through the API requires read:activity. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["email.received"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"email_id":{},"company_id":{},"contact_id":{},"job_id":{},"created_at":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"form.submitted":{"post":{"operationId":"webhook_form_submitted","summary":"A website or contact form was submitted. Answers are not included.","tags":["Outbound Webhooks"],"description":"A website or contact form was submitted. Answers are not included. Subscribing through the API requires read:activity. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["form.submitted"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"form_id":{},"source_kind":{},"website_config_id":{},"contact_id":{},"company_id":{},"created_at":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"promoter.enrolled":{"post":{"operationId":"webhook_promoter_enrolled","summary":"A customer, partner or employee joined a referral program.","tags":["Outbound Webhooks"],"description":"A customer, partner or employee joined a referral program. Subscribing through the API requires read:referrals. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["promoter.enrolled"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"campaign_id":{},"promoter_id":{},"attribution_id":{},"actor_type":{},"amount":{},"payout_request_id":{},"reward_id":{},"source":{},"created_at":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"referral.clicked":{"post":{"operationId":"webhook_referral_clicked","summary":"Someone opened a referral link.","tags":["Outbound Webhooks"],"description":"Someone opened a referral link. Subscribing through the API requires read:referrals. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["referral.clicked"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"campaign_id":{},"promoter_id":{},"attribution_id":{},"actor_type":{},"amount":{},"payout_request_id":{},"reward_id":{},"source":{},"created_at":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"referral.lead":{"post":{"operationId":"webhook_referral_lead","summary":"A referred person became a lead.","tags":["Outbound Webhooks"],"description":"A referred person became a lead. Subscribing through the API requires read:referrals. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["referral.lead"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"campaign_id":{},"promoter_id":{},"attribution_id":{},"actor_type":{},"amount":{},"payout_request_id":{},"reward_id":{},"source":{},"created_at":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"referral.booked":{"post":{"operationId":"webhook_referral_booked","summary":"A referred person booked work.","tags":["Outbound Webhooks"],"description":"A referred person booked work. Subscribing through the API requires read:referrals. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["referral.booked"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"campaign_id":{},"promoter_id":{},"attribution_id":{},"actor_type":{},"amount":{},"payout_request_id":{},"reward_id":{},"source":{},"created_at":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"referral.flagged":{"post":{"operationId":"webhook_referral_flagged","summary":"A referral was flagged for review.","tags":["Outbound Webhooks"],"description":"A referral was flagged for review. Subscribing through the API requires read:referrals. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["referral.flagged"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"campaign_id":{},"promoter_id":{},"attribution_id":{},"actor_type":{},"amount":{},"payout_request_id":{},"reward_id":{},"source":{},"created_at":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"referral.qualified":{"post":{"operationId":"webhook_referral_qualified","summary":"A referral met its program's qualification rule.","tags":["Outbound Webhooks"],"description":"A referral met its program's qualification rule. Subscribing through the API requires read:referrals. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["referral.qualified"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"campaign_id":{},"promoter_id":{},"attribution_id":{},"actor_type":{},"amount":{},"payout_request_id":{},"reward_id":{},"source":{},"created_at":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"referral.reversed":{"post":{"operationId":"webhook_referral_reversed","summary":"A qualified referral was reversed.","tags":["Outbound Webhooks"],"description":"A qualified referral was reversed. Subscribing through the API requires read:referrals. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["referral.reversed"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"campaign_id":{},"promoter_id":{},"attribution_id":{},"actor_type":{},"amount":{},"payout_request_id":{},"reward_id":{},"source":{},"created_at":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"reward.available":{"post":{"operationId":"webhook_reward_available","summary":"A cash referral reward became available.","tags":["Outbound Webhooks"],"description":"A cash referral reward became available. Subscribing through the API requires read:referrals. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["reward.available"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"campaign_id":{},"promoter_id":{},"attribution_id":{},"actor_type":{},"amount":{},"payout_request_id":{},"reward_id":{},"source":{},"created_at":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"reward.credited":{"post":{"operationId":"webhook_reward_credited","summary":"A referral reward was applied as account credit.","tags":["Outbound Webhooks"],"description":"A referral reward was applied as account credit. Subscribing through the API requires read:referrals. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["reward.credited"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"campaign_id":{},"promoter_id":{},"attribution_id":{},"actor_type":{},"amount":{},"payout_request_id":{},"reward_id":{},"source":{},"created_at":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"reward.cancelled":{"post":{"operationId":"webhook_reward_cancelled","summary":"A referral reward was cancelled.","tags":["Outbound Webhooks"],"description":"A referral reward was cancelled. Subscribing through the API requires read:referrals. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["reward.cancelled"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"campaign_id":{},"promoter_id":{},"attribution_id":{},"actor_type":{},"amount":{},"payout_request_id":{},"reward_id":{},"source":{},"created_at":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"reward.cap_reached":{"post":{"operationId":"webhook_reward_cap_reached","summary":"A promoter reached their program's reward limit.","tags":["Outbound Webhooks"],"description":"A promoter reached their program's reward limit. Subscribing through the API requires read:referrals. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["reward.cap_reached"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"campaign_id":{},"promoter_id":{},"attribution_id":{},"actor_type":{},"amount":{},"payout_request_id":{},"reward_id":{},"source":{},"created_at":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"reward.clawback_recovered":{"post":{"operationId":"webhook_reward_clawback_recovered","summary":"A reversed reward was recovered.","tags":["Outbound Webhooks"],"description":"A reversed reward was recovered. Subscribing through the API requires read:referrals. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["reward.clawback_recovered"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"campaign_id":{},"promoter_id":{},"attribution_id":{},"actor_type":{},"amount":{},"payout_request_id":{},"reward_id":{},"source":{},"created_at":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"payout.requested":{"post":{"operationId":"webhook_payout_requested","summary":"A referral payout was requested.","tags":["Outbound Webhooks"],"description":"A referral payout was requested. Subscribing through the API requires read:referrals. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["payout.requested"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"campaign_id":{},"promoter_id":{},"attribution_id":{},"actor_type":{},"amount":{},"payout_request_id":{},"reward_id":{},"source":{},"created_at":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"payout.paid":{"post":{"operationId":"webhook_payout_paid","summary":"A referral payout was paid.","tags":["Outbound Webhooks"],"description":"A referral payout was paid. Subscribing through the API requires read:referrals. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["payout.paid"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"campaign_id":{},"promoter_id":{},"attribution_id":{},"actor_type":{},"amount":{},"payout_request_id":{},"reward_id":{},"source":{},"created_at":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"service.created":{"post":{"operationId":"webhook_service_created","summary":"A service was added to the catalog.","tags":["Outbound Webhooks"],"description":"A service was added to the catalog. Subscribing through the API requires read:services. Organization-wide: company-restricted endpoints do not receive it. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["service.created"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"name":{},"company_ids":{},"updated_at":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"service.updated":{"post":{"operationId":"webhook_service_updated","summary":"A catalog service changed.","tags":["Outbound Webhooks"],"description":"A catalog service changed. Subscribing through the API requires read:services. Organization-wide: company-restricted endpoints do not receive it. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["service.updated"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"name":{},"company_ids":{},"updated_at":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"service.deleted":{"post":{"operationId":"webhook_service_deleted","summary":"A catalog service was deleted.","tags":["Outbound Webhooks"],"description":"A catalog service was deleted. Subscribing through the API requires read:services. Organization-wide: company-restricted endpoints do not receive it. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["service.deleted"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"deleted_at":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"product.created":{"post":{"operationId":"webhook_product_created","summary":"A product was added to the catalog.","tags":["Outbound Webhooks"],"description":"A product was added to the catalog. Subscribing through the API requires read:products. Organization-wide: company-restricted endpoints do not receive it. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["product.created"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"name":{},"company_ids":{},"updated_at":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"product.updated":{"post":{"operationId":"webhook_product_updated","summary":"A catalog product changed.","tags":["Outbound Webhooks"],"description":"A catalog product changed. Subscribing through the API requires read:products. Organization-wide: company-restricted endpoints do not receive it. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["product.updated"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"name":{},"company_ids":{},"updated_at":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"product.deleted":{"post":{"operationId":"webhook_product_deleted","summary":"A catalog product was deleted.","tags":["Outbound Webhooks"],"description":"A catalog product was deleted. Subscribing through the API requires read:products. Organization-wide: company-restricted endpoints do not receive it. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["product.deleted"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"deleted_at":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"company.created":{"post":{"operationId":"webhook_company_created","summary":"A company (brand) was added.","tags":["Outbound Webhooks"],"description":"A company (brand) was added. Subscribing through the API requires read:companies. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["company.created"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"name":{},"public_name":{},"timezone":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"company.updated":{"post":{"operationId":"webhook_company_updated","summary":"A company's name, public name or time zone changed.","tags":["Outbound Webhooks"],"description":"A company's name, public name or time zone changed. Subscribing through the API requires read:companies. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["company.updated"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"name":{},"public_name":{},"timezone":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}},"company.deleted":{"post":{"operationId":"webhook_company_deleted","summary":"A company was deleted.","tags":["Outbound Webhooks"],"description":"A company was deleted. Subscribing through the API requires read:companies. Organization-wide: company-restricted endpoints do not receive it. Verify X-WildPipe-Signature before trusting the body.","parameters":[{"name":"X-WildPipe-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"t=<unix-seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\">; during secret rotation more than one v1 is sent."},{"name":"X-Webhook-Delivery","in":"header","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-Webhook-Event","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WildPipe-Attempt","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WildPipe-Endpoint","in":"header","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","event","api_version","created_at","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event ID; also sent as X-Webhook-Delivery. Deduplicate on it."},"event":{"type":"string","enum":["company.deleted"]},"api_version":{"type":"string","enum":["1"]},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","properties":{"id":{},"company_id":{},"deleted_at":{}}},"record":{"type":"object","nullable":true,"description":"Present only for endpoints using payload_mode=full: the record's API summary, read before the first attempt (null when unavailable)."}}}}}},"responses":{"2XX":{"description":"Acknowledged. Persist the event before responding."},"default":{"description":"Retried on network errors, 408, 425, 429 and 5xx (up to 8 attempts); other statuses fail immediately."}}}}},"externalDocs":{"description":"Guides & Webhooks","url":"https://wildpipe.com/developers/api"},"servers":[{"url":"https://api.wildpipe.com/v1"}],"security":[{"ApiKey":[]}],"components":{"securitySchemes":{"ApiKey":{"type":"apiKey","in":"header","name":"X-API-Key"},"InboundSignature":{"type":"apiKey","in":"header","name":"X-WildPipe-Signature"}}},"paths":{"/contacts":{"get":{"operationId":"list_contacts","summary":"List contacts summaries","description":"Requires read:contacts. Explicit returned fields: id,company_id,first_name,last_name,email,phone,contact_type,company_name,credit_balance,tag_ids,created_at,updated_at, app_url. Ordered by created_at then id; sort=-created_at reverses both. Search fields: first_name, last_name, email, phone. Pages are not a point-in-time snapshot, so changes made while you page can affect later pages.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":8192},"description":"Opaque next_cursor from the previous response; repeat the same filters and sort on every page."},{"name":"company_id","in":"query","schema":{"type":"string","format":"uuid"},"description":"Exact direct-record reference match within the authorized organization. Multiple filters use AND, not relationship expansion. Each parameter may appear only once."},{"name":"search","in":"query","schema":{"type":"string","maxLength":200},"description":"Literal case-insensitive substring across this resource’s searchable summary fields; punctuation is data, not filter syntax. Names are matched per field, not concatenated."},{"name":"statuses","in":"query","schema":{"type":"string","maxLength":810,"description":"Comma-separated exact stored statuses (OR within the list, AND with other filters). Up to 10 values. Contacts use contact_type; tasks use numeric status_id."},"description":"Narrows approved access. Repeat on subsequent pages. Each parameter may appear only once."},{"name":"created_from","in":"query","schema":{"type":"string","format":"date-time","description":"Inclusive ISO 8601 timestamp with timezone. Date-only values are also accepted at UTC midnight."},"description":"Narrows approved access. Repeat on subsequent pages. Each parameter may appear only once."},{"name":"created_to","in":"query","schema":{"type":"string","format":"date-time","description":"Inclusive ISO 8601 timestamp with timezone. Date-only values are also accepted at UTC midnight."},"description":"Narrows approved access. Repeat on subsequent pages. Each parameter may appear only once."},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time","description":"Inclusive ISO 8601 timestamp with timezone. Date-only values are also accepted at UTC midnight."},"description":"Narrows approved access. Repeat on subsequent pages. Each parameter may appear only once."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time","description":"Inclusive ISO 8601 timestamp with timezone. Date-only values are also accepted at UTC midnight."},"description":"Narrows approved access. Repeat on subsequent pages. Each parameter may appear only once."},{"name":"sort","in":"query","schema":{"type":"string","enum":["created_at","-created_at"],"default":"created_at"},"description":"Narrows approved access. Repeat on subsequent pages. Each parameter may appear only once."}],"responses":{"200":{"description":"Resource summaries and cursor","content":{"application/json":{"schema":{"type":"object","required":["data","next_cursor","has_more"],"properties":{"data":{"type":"array","items":{"type":"object"}},"next_cursor":{"type":"string","nullable":true},"has_more":{"type":"boolean"}}}}}},"400":{"description":"Invalid parameters"},"401":{"description":"Missing, invalid, expired, or revoked key"},"403":{"description":"Missing explicit scope or inactive/restricted key owner"},"429":{"description":"Rate limit exceeded: 120 requests per minute per key"},"500":{"description":"The request could not be completed; nothing is reported as success"}},"tags":["Customers"]},"post":{"operationId":"create_contact","summary":"Idempotently create a contact","description":"Requires write:contacts. Does not grant communication consent. Receipt retained indefinitely; retry with exactly the same body bytes and key.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"first_name":{"type":"string","nullable":true},"last_name":{"type":"string","nullable":true},"email":{"type":"string","nullable":true},"phone":{"type":"string","nullable":true},"company":{"type":"string","nullable":true},"address":{"type":"string","nullable":true},"city":{"type":"string","nullable":true},"state":{"type":"string","nullable":true},"zip":{"type":"string","nullable":true},"notes":{"type":"string","nullable":true}}}}}},"responses":{"200":{"description":"Stored result replayed without another mutation"},"201":{"description":"Contact and outbound event committed atomically"},"400":{"description":"Invalid parameters"},"401":{"description":"Missing, invalid, expired, or revoked key"},"403":{"description":"Missing explicit scope or inactive/restricted key owner"},"409":{"description":"Event/idempotency key reused with different exact body bytes"},"422":{"description":"Invalid input or mapping"},"429":{"description":"Rate limit exceeded: 120 requests per minute per key"},"500":{"description":"The request could not be completed; nothing is reported as success"},"503":{"description":"Transaction unavailable; retry the same identity and bytes"}},"tags":["Customers"]}},"/contacts/{id}":{"get":{"operationId":"get_contacts","summary":"Retrieve one contacts summary","description":"Requires read:contacts. Uses the same field allowlist as the list endpoint.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Resource summary","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"400":{"description":"Invalid parameters"},"401":{"description":"Missing, invalid, expired, or revoked key"},"403":{"description":"Missing explicit scope or inactive/restricted key owner"},"404":{"description":"Record not found in the authorized organization"},"429":{"description":"Rate limit exceeded: 120 requests per minute per key"},"500":{"description":"The request could not be completed; nothing is reported as success"}},"tags":["Customers"]},"patch":{"operationId":"update_contacts_metadata","summary":"Replace contact notes","description":"Requires write:contacts. Only notes may change. Omitted fields are preserved; null clears a field. Follow-up dates must be real UTC timestamps in YYYY-MM-DDTHH:mm:ssZ or YYYY-MM-DDTHH:mm:ss.SSSZ format (years 0001–9999). This sets a follow-up reminder, not an appointment. No identity, company, consent, status, booking or financial changes. Updates replace values (not append); distinct request keys are last-writer-wins. Repeating the same key/target/exact body returns the original receipt without reapplying an older update.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"minProperties":1,"properties":{"notes":{"type":"string","nullable":true,"maxLength":10000}}}}}},"responses":{"200":{"description":"Atomic update or original replay: data contains id, company_id and updated_fields; replayed is boolean. No note contents returned."},"400":{"description":"Invalid parameters"},"401":{"description":"Missing, invalid, expired, or revoked key"},"403":{"description":"Missing explicit scope or inactive/restricted key owner"},"409":{"description":"Key reused with different body or target within this resource update family"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or body larger than 32 KiB"},"429":{"description":"Rate limit exceeded: 120 requests per minute per key"},"500":{"description":"The request could not be completed; nothing is reported as success"},"503":{"description":"Retry same target, key and exact bytes; no partial transaction is committed"}},"tags":["Customers"]},"delete":{"operationId":"contact_delete","summary":"Delete an unused customer","description":"Requires write:record_deletions. Deletes a customer record that has no jobs, visits, quotes, invoices, payments, leads, credits, agreements, warranties, concerns, documents, cameras or conversations. Customers with any history are refused; merge duplicates with POST /contacts/{id}/merge instead. Retrying with the same Idempotency-Key and identical content returns the original result without repeating the change. Recover a lost response with GET /operations/contact_delete/{key}.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}},{"name":"expected_updated_at","in":"query","required":true,"schema":{"type":"string","format":"date-time","description":"The updated_at you last read. A newer value is refused with 409."}}],"responses":{"200":{"description":"Committed, or the original result of an identical retry"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Customers"]}},"/jobs":{"get":{"operationId":"list_jobs","summary":"List jobs summaries","description":"Requires read:jobs. Explicit returned fields: id,company_id,contact_id,booking_number,address,status,phase,service_domain,billing_type,created_at,updated_at, app_url. Ordered by created_at then id; sort=-created_at reverses both. Search fields: address, booking_number. Pages are not a point-in-time snapshot, so changes made while you page can affect later pages.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":8192},"description":"Opaque next_cursor from the previous response; repeat the same filters and sort on every page."},{"name":"company_id","in":"query","schema":{"type":"string","format":"uuid"},"description":"Exact direct-record reference match within the authorized organization. Multiple filters use AND, not relationship expansion. Each parameter may appear only once."},{"name":"contact_id","in":"query","schema":{"type":"string","format":"uuid"},"description":"Exact direct-record reference match within the authorized organization. Multiple filters use AND, not relationship expansion. Each parameter may appear only once."},{"name":"search","in":"query","schema":{"type":"string","maxLength":200},"description":"Literal case-insensitive substring across this resource’s searchable summary fields; punctuation is data, not filter syntax. Names are matched per field, not concatenated."},{"name":"statuses","in":"query","schema":{"type":"string","maxLength":810,"description":"Comma-separated exact stored statuses (OR within the list, AND with other filters). Up to 10 values. Contacts use contact_type; tasks use numeric status_id."},"description":"Narrows approved access. Repeat on subsequent pages. Each parameter may appear only once."},{"name":"created_from","in":"query","schema":{"type":"string","format":"date-time","description":"Inclusive ISO 8601 timestamp with timezone. Date-only values are also accepted at UTC midnight."},"description":"Narrows approved access. Repeat on subsequent pages. Each parameter may appear only once."},{"name":"created_to","in":"query","schema":{"type":"string","format":"date-time","description":"Inclusive ISO 8601 timestamp with timezone. Date-only values are also accepted at UTC midnight."},"description":"Narrows approved access. Repeat on subsequent pages. Each parameter may appear only once."},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time","description":"Inclusive ISO 8601 timestamp with timezone. Date-only values are also accepted at UTC midnight."},"description":"Narrows approved access. Repeat on subsequent pages. Each parameter may appear only once."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time","description":"Inclusive ISO 8601 timestamp with timezone. Date-only values are also accepted at UTC midnight."},"description":"Narrows approved access. Repeat on subsequent pages. Each parameter may appear only once."},{"name":"sort","in":"query","schema":{"type":"string","enum":["created_at","-created_at"],"default":"created_at"},"description":"Narrows approved access. Repeat on subsequent pages. Each parameter may appear only once."}],"responses":{"200":{"description":"Resource summaries and cursor","content":{"application/json":{"schema":{"type":"object","required":["data","next_cursor","has_more"],"properties":{"data":{"type":"array","items":{"type":"object"}},"next_cursor":{"type":"string","nullable":true},"has_more":{"type":"boolean"}}}}}},"400":{"description":"Invalid parameters"},"401":{"description":"Missing, invalid, expired, or revoked key"},"403":{"description":"Missing explicit scope or inactive/restricted key owner"},"429":{"description":"Rate limit exceeded: 120 requests per minute per key"},"500":{"description":"The request could not be completed; nothing is reported as success"}},"tags":["Jobs"]},"post":{"operationId":"job_create","summary":"Create a job for a customer","description":"Requires write:jobs. Creates a job (project) in the initial inspection phase at one of the customer's saved properties (the primary service property when service_address_id is omitted), links the customer as primary contact and, like the office, marks that company's open leads for the customer won. A job is not an appointment: add visits with POST /tasks and POST /tasks/{id}/schedule, or book with POST /appointments. company_id is required only for a customer without a company in an organization with several. Retrying with the same Idempotency-Key and identical content returns the original result without repeating the change. Recover a lost response with GET /operations/job_create/{key}.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["contact_id"],"properties":{"contact_id":{"type":"string","format":"uuid"},"company_id":{"type":"string","format":"uuid"},"service_address_id":{"type":"string","format":"uuid"},"appointment_type":{"type":"string","maxLength":100,"nullable":true},"notes":{"type":"string","maxLength":20000,"nullable":true}}}}}},"responses":{"200":{"description":"Original result of an identical retry (replayed true)"},"201":{"description":"Committed; data holds the result and replayed is false"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Jobs"]}},"/jobs/{id}":{"get":{"operationId":"get_jobs","summary":"Retrieve one jobs summary","description":"Requires read:jobs. Uses the same field allowlist as the list endpoint.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Resource summary","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"400":{"description":"Invalid parameters"},"401":{"description":"Missing, invalid, expired, or revoked key"},"403":{"description":"Missing explicit scope or inactive/restricted key owner"},"404":{"description":"Record not found in the authorized organization"},"429":{"description":"Rate limit exceeded: 120 requests per minute per key"},"500":{"description":"The request could not be completed; nothing is reported as success"}},"tags":["Jobs"]},"patch":{"operationId":"update_job_authored_notes","summary":"Replace reviewed authored job notes","description":"Requires separately approved write:job_notes and unrestricted company access. JSON limit 128 KiB. Supply the reviewed updated_at and a reason. Empty notes clears the text. The update, its audit record and the request receipt are saved together. No phase, task instructions, assignment, schedule, company, property, price, payment or notification changes. Conflicts require fresh review; never repeat uncertainty under a new identity.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["expected_updated_at","notes","reason"],"properties":{"expected_updated_at":{"type":"string","format":"date-time","maxLength":64},"notes":{"type":"string","maxLength":20000},"reason":{"type":"string","minLength":1,"maxLength":1000}}}}}},"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Jobs"]}},"/tasks":{"get":{"operationId":"list_tasks","summary":"List tasks summaries","description":"Requires read:tasks. Explicit returned fields: id,company_id,job_id,contact_id,title,status_id,status_desc,task_type_ref,route_stop_type,is_appointment,is_all_day,arrive_by,start_time,end_time,arrival_window_start,arrival_window_end,assigned_to_driver_user_id,completed_time,created_at,updated_at, app_url. Ordered by created_at then id; sort=-created_at reverses both. Search fields: title, status_desc, route_stop_type. Pages are not a point-in-time snapshot, so changes made while you page can affect later pages.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":8192},"description":"Opaque next_cursor from the previous response; repeat the same filters and sort on every page."},{"name":"company_id","in":"query","schema":{"type":"string","format":"uuid"},"description":"Exact direct-record reference match within the authorized organization. Multiple filters use AND, not relationship expansion. Each parameter may appear only once."},{"name":"contact_id","in":"query","schema":{"type":"string","format":"uuid"},"description":"Exact direct-record reference match within the authorized organization. Multiple filters use AND, not relationship expansion. Each parameter may appear only once."},{"name":"job_id","in":"query","schema":{"type":"string","format":"uuid"},"description":"Exact direct-record reference match within the authorized organization. Multiple filters use AND, not relationship expansion. Each parameter may appear only once."},{"name":"search","in":"query","schema":{"type":"string","maxLength":200},"description":"Literal case-insensitive substring across this resource’s searchable summary fields; punctuation is data, not filter syntax. Names are matched per field, not concatenated."},{"name":"statuses","in":"query","schema":{"type":"string","maxLength":810,"description":"Comma-separated exact stored statuses (OR within the list, AND with other filters). Up to 10 values. Contacts use contact_type; tasks use numeric status_id."},"description":"Narrows approved access. Repeat on subsequent pages. Each parameter may appear only once."},{"name":"assigned_to","in":"query","schema":{"type":"string","format":"uuid"},"description":"Narrows approved access. Repeat on subsequent pages. Each parameter may appear only once."},{"name":"is_appointment","in":"query","schema":{"type":"boolean"},"description":"Narrows approved access. Repeat on subsequent pages. Each parameter may appear only once."},{"name":"start_from","in":"query","schema":{"type":"string","format":"date-time","description":"Inclusive ISO 8601 timestamp with timezone. Date-only values are also accepted at UTC midnight."},"description":"Narrows approved access. Repeat on subsequent pages. Each parameter may appear only once."},{"name":"start_to","in":"query","schema":{"type":"string","format":"date-time","description":"Inclusive ISO 8601 timestamp with timezone. Date-only values are also accepted at UTC midnight."},"description":"Narrows approved access. Repeat on subsequent pages. Each parameter may appear only once."},{"name":"created_from","in":"query","schema":{"type":"string","format":"date-time","description":"Inclusive ISO 8601 timestamp with timezone. Date-only values are also accepted at UTC midnight."},"description":"Narrows approved access. Repeat on subsequent pages. Each parameter may appear only once."},{"name":"created_to","in":"query","schema":{"type":"string","format":"date-time","description":"Inclusive ISO 8601 timestamp with timezone. Date-only values are also accepted at UTC midnight."},"description":"Narrows approved access. Repeat on subsequent pages. Each parameter may appear only once."},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time","description":"Inclusive ISO 8601 timestamp with timezone. Date-only values are also accepted at UTC midnight."},"description":"Narrows approved access. Repeat on subsequent pages. Each parameter may appear only once."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time","description":"Inclusive ISO 8601 timestamp with timezone. Date-only values are also accepted at UTC midnight."},"description":"Narrows approved access. Repeat on subsequent pages. Each parameter may appear only once."},{"name":"sort","in":"query","schema":{"type":"string","enum":["created_at","-created_at"],"default":"created_at"},"description":"Narrows approved access. Repeat on subsequent pages. Each parameter may appear only once."}],"responses":{"200":{"description":"Resource summaries and cursor","content":{"application/json":{"schema":{"type":"object","required":["data","next_cursor","has_more"],"properties":{"data":{"type":"array","items":{"type":"object"}},"next_cursor":{"type":"string","nullable":true},"has_more":{"type":"boolean"}}}}}},"400":{"description":"Invalid parameters"},"401":{"description":"Missing, invalid, expired, or revoked key"},"403":{"description":"Missing explicit scope or inactive/restricted key owner"},"429":{"description":"Rate limit exceeded: 120 requests per minute per key"},"500":{"description":"The request could not be completed; nothing is reported as success"}},"tags":["Tasks & Visits"]},"post":{"operationId":"create_task","summary":"Create a task","description":"Requires write:tasks and unrestricted company access. Uses the same workflow as the office and is attempted exactly once per request key. Tasks are unassigned/unscheduled work on an existing job; quotes are unsent one-time live-catalog drafts with exact variants, not accepted orders. Appointments reuse the active company widget and its booking/payment/availability rules at an existing property; deposit and recurring plans use customer-facing workflows. Provider and uncertain writes are never automatically repeated.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["job_id","task_type_id","instructions"],"properties":{"job_id":{"type":"string","format":"uuid"},"task_type_id":{"type":"string","format":"uuid"},"instructions":{"type":"string","maxLength":10000},"stop_reason":{"type":"string","maxLength":200},"duration":{"type":"integer","minimum":1,"maximum":480},"work_scope_quote_id":{"type":"string","format":"uuid"}}}}}},"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Tasks & Visits"]}},"/tasks/{id}":{"get":{"operationId":"get_tasks","summary":"Retrieve one tasks summary","description":"Requires read:tasks. Uses the same field allowlist as the list endpoint.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Resource summary","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"400":{"description":"Invalid parameters"},"401":{"description":"Missing, invalid, expired, or revoked key"},"403":{"description":"Missing explicit scope or inactive/restricted key owner"},"404":{"description":"Record not found in the authorized organization"},"429":{"description":"Rate limit exceeded: 120 requests per minute per key"},"500":{"description":"The request could not be completed; nothing is reported as success"}},"tags":["Tasks & Visits"]},"patch":{"operationId":"update_task_instructions","summary":"Replace reviewed task title and instructions","description":"Requires separate write:task_instructions and unrestricted company access. JSON limit 128 KiB. First review instructions and supply expected_updated_at. Only open non-crew work is eligible. Empty notes explicitly clears instructions. The update, a permanent revision record, an audit record and the receipt are saved together. No assignment, timing, status, classification, scope, equipment, payment, completion or customer/technician notification changes. Conflicts require fresh review; never repeat uncertainty with a new identity.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["expected_updated_at","title","notes","reason"],"properties":{"expected_updated_at":{"type":"string","format":"date-time","maxLength":64},"title":{"type":"string","minLength":1,"maxLength":500},"notes":{"type":"string","maxLength":20000},"reason":{"type":"string","minLength":1,"maxLength":1000}}}}}},"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Tasks & Visits"]}},"/quotes":{"get":{"operationId":"list_quotes","summary":"List quotes summaries","description":"Requires read:quotes. Explicit returned fields: id,company_id,job_id,contact_id,quote_number,status,issue_date,expiry_date,subtotal,tax,total,discount_total,version,parent_quote_id,created_at,updated_at, app_url. Ordered by created_at then id; sort=-created_at reverses both. Search fields: quote_number. Pages are not a point-in-time snapshot, so changes made while you page can affect later pages.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":8192},"description":"Opaque next_cursor from the previous response; repeat the same filters and sort on every page."},{"name":"company_id","in":"query","schema":{"type":"string","format":"uuid"},"description":"Exact direct-record reference match within the authorized organization. Multiple filters use AND, not relationship expansion. Each parameter may appear only once."},{"name":"contact_id","in":"query","schema":{"type":"string","format":"uuid"},"description":"Exact direct-record reference match within the authorized organization. Multiple filters use AND, not relationship expansion. Each parameter may appear only once."},{"name":"job_id","in":"query","schema":{"type":"string","format":"uuid"},"description":"Exact direct-record reference match within the authorized organization. Multiple filters use AND, not relationship expansion. Each parameter may appear only once."},{"name":"search","in":"query","schema":{"type":"string","maxLength":200},"description":"Literal case-insensitive substring across this resource’s searchable summary fields; punctuation is data, not filter syntax. Names are matched per field, not concatenated."},{"name":"statuses","in":"query","schema":{"type":"string","maxLength":810,"description":"Comma-separated exact stored statuses (OR within the list, AND with other filters). Up to 10 values. Contacts use contact_type; tasks use numeric status_id."},"description":"Narrows approved access. Repeat on subsequent pages. Each parameter may appear only once."},{"name":"total_min","in":"query","schema":{"type":"number","minimum":0,"maximum":1000000000},"description":"Narrows approved access. Repeat on subsequent pages. Each parameter may appear only once."},{"name":"total_max","in":"query","schema":{"type":"number","minimum":0,"maximum":1000000000},"description":"Narrows approved access. Repeat on subsequent pages. Each parameter may appear only once."},{"name":"created_from","in":"query","schema":{"type":"string","format":"date-time","description":"Inclusive ISO 8601 timestamp with timezone. Date-only values are also accepted at UTC midnight."},"description":"Narrows approved access. Repeat on subsequent pages. Each parameter may appear only once."},{"name":"created_to","in":"query","schema":{"type":"string","format":"date-time","description":"Inclusive ISO 8601 timestamp with timezone. Date-only values are also accepted at UTC midnight."},"description":"Narrows approved access. Repeat on subsequent pages. Each parameter may appear only once."},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time","description":"Inclusive ISO 8601 timestamp with timezone. Date-only values are also accepted at UTC midnight."},"description":"Narrows approved access. Repeat on subsequent pages. Each parameter may appear only once."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time","description":"Inclusive ISO 8601 timestamp with timezone. Date-only values are also accepted at UTC midnight."},"description":"Narrows approved access. Repeat on subsequent pages. Each parameter may appear only once."},{"name":"sort","in":"query","schema":{"type":"string","enum":["created_at","-created_at"],"default":"created_at"},"description":"Narrows approved access. Repeat on subsequent pages. Each parameter may appear only once."}],"responses":{"200":{"description":"Resource summaries and cursor","content":{"application/json":{"schema":{"type":"object","required":["data","next_cursor","has_more"],"properties":{"data":{"type":"array","items":{"type":"object"}},"next_cursor":{"type":"string","nullable":true},"has_more":{"type":"boolean"}}}}}},"400":{"description":"Invalid parameters"},"401":{"description":"Missing, invalid, expired, or revoked key"},"403":{"description":"Missing explicit scope or inactive/restricted key owner"},"429":{"description":"Rate limit exceeded: 120 requests per minute per key"},"500":{"description":"The request could not be completed; nothing is reported as success"}},"tags":["Quotes"]},"post":{"operationId":"create_quote","summary":"Create a quote","description":"Requires write:quotes and unrestricted company access. Uses the same workflow as the office and is attempted exactly once per request key. Tasks are unassigned/unscheduled work on an existing job; quotes are unsent one-time live-catalog drafts with exact variants, not accepted orders. Appointments reuse the active company widget and its booking/payment/availability rules at an existing property; deposit and recurring plans use customer-facing workflows. Provider and uncertain writes are never automatically repeated.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["contact_id","service_id"],"properties":{"contact_id":{"type":"string","format":"uuid"},"service_id":{"type":"string","format":"uuid"},"variant_id":{"type":"string","format":"uuid"},"quantity":{"type":"integer","minimum":1,"maximum":100},"notes":{"type":"string","maxLength":10000}}}}}},"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Quotes"]}},"/quotes/{id}":{"get":{"operationId":"get_quotes","summary":"Retrieve one quotes summary","description":"Requires read:quotes. Uses the same field allowlist as the list endpoint.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Resource summary","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"400":{"description":"Invalid parameters"},"401":{"description":"Missing, invalid, expired, or revoked key"},"403":{"description":"Missing explicit scope or inactive/restricted key owner"},"404":{"description":"Record not found in the authorized organization"},"429":{"description":"Rate limit exceeded: 120 requests per minute per key"},"500":{"description":"The request could not be completed; nothing is reported as success"}},"tags":["Quotes"]},"patch":{"operationId":"quote_update","summary":"Edit an unaccepted quote","description":"Requires write:quote_edits. Changes items, notes, expiry date or discount on a draft or sent quote that has no acceptance, signature, decline or invoice. Accepted quotes change only through POST /quotes/{id}/revise. Item category controls whether the customer may leave an item out. Retrying with the same Idempotency-Key and identical content returns the original result without repeating the change. Recover a lost response with GET /operations/quote_update/{key}.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["expected_updated_at"],"properties":{"expected_updated_at":{"type":"string","format":"date-time","description":"The updated_at you last read. A newer value is refused with 409."},"line_items":{"type":"array","minItems":1,"maxItems":200,"items":{"type":"object","additionalProperties":false,"required":["name","quantity","unit_price"],"properties":{"name":{"type":"string","minLength":1,"maxLength":300},"description":{"type":"string","maxLength":5000,"nullable":true},"quantity":{"type":"number","exclusiveMinimum":0,"maximum":100000},"unit_price":{"type":"number","minimum":0,"maximum":1000000,"multipleOf":0.01},"is_taxable":{"type":"boolean","default":true},"discount_type":{"type":"string","enum":["percentage","fixed"]},"discount_value":{"type":"number","minimum":0},"service_id":{"type":"string","format":"uuid"},"product_id":{"type":"string","format":"uuid"},"variant_id":{"type":"string","format":"uuid"},"category":{"type":"string","enum":["required","recommended","optional"],"default":"required"}}},"description":"Replaces every line item, in this order. Totals and tax are calculated by WildPipe."},"notes":{"type":"string","maxLength":20000,"nullable":true},"expiry_date":{"type":"string","format":"date","nullable":true},"discount_type":{"type":"string","enum":["percentage","fixed"],"nullable":true},"discount_value":{"type":"number","minimum":0}}}}}},"responses":{"200":{"description":"Committed, or the original result of an identical retry"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Quotes"]}},"/invoices":{"get":{"operationId":"list_invoices","summary":"List invoices summaries","description":"Requires read:invoices. Explicit returned fields: id,company_id,job_id,contact_id,quote_id,invoice_number,status,issue_date,due_date,subtotal,tax,total,amount_paid,balance,created_at,updated_at, app_url. Ordered by created_at then id; sort=-created_at reverses both. Search fields: invoice_number. Pages are not a point-in-time snapshot, so changes made while you page can affect later pages.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":8192},"description":"Opaque next_cursor from the previous response; repeat the same filters and sort on every page."},{"name":"company_id","in":"query","schema":{"type":"string","format":"uuid"},"description":"Exact direct-record reference match within the authorized organization. Multiple filters use AND, not relationship expansion. Each parameter may appear only once."},{"name":"contact_id","in":"query","schema":{"type":"string","format":"uuid"},"description":"Exact direct-record reference match within the authorized organization. Multiple filters use AND, not relationship expansion. Each parameter may appear only once."},{"name":"job_id","in":"query","schema":{"type":"string","format":"uuid"},"description":"Exact direct-record reference match within the authorized organization. Multiple filters use AND, not relationship expansion. Each parameter may appear only once."},{"name":"quote_id","in":"query","schema":{"type":"string","format":"uuid"},"description":"Exact direct-record reference match within the authorized organization. Multiple filters use AND, not relationship expansion. Each parameter may appear only once."},{"name":"search","in":"query","schema":{"type":"string","maxLength":200},"description":"Literal case-insensitive substring across this resource’s searchable summary fields; punctuation is data, not filter syntax. Names are matched per field, not concatenated."},{"name":"statuses","in":"query","schema":{"type":"string","maxLength":810,"description":"Comma-separated exact stored statuses (OR within the list, AND with other filters). Up to 10 values. Contacts use contact_type; tasks use numeric status_id."},"description":"Narrows approved access. Repeat on subsequent pages. Each parameter may appear only once."},{"name":"total_min","in":"query","schema":{"type":"number","minimum":0,"maximum":1000000000},"description":"Narrows approved access. Repeat on subsequent pages. Each parameter may appear only once."},{"name":"total_max","in":"query","schema":{"type":"number","minimum":0,"maximum":1000000000},"description":"Narrows approved access. Repeat on subsequent pages. Each parameter may appear only once."},{"name":"balance_min","in":"query","schema":{"type":"number","minimum":0,"maximum":1000000000},"description":"Narrows approved access. Repeat on subsequent pages. Each parameter may appear only once."},{"name":"balance_max","in":"query","schema":{"type":"number","minimum":0,"maximum":1000000000},"description":"Narrows approved access. Repeat on subsequent pages. Each parameter may appear only once."},{"name":"due_from","in":"query","schema":{"type":"string","format":"date-time","description":"Inclusive ISO 8601 timestamp with timezone. Date-only values are also accepted at UTC midnight."},"description":"Narrows approved access. Repeat on subsequent pages. Each parameter may appear only once."},{"name":"due_to","in":"query","schema":{"type":"string","format":"date-time","description":"Inclusive ISO 8601 timestamp with timezone. Date-only values are also accepted at UTC midnight."},"description":"Narrows approved access. Repeat on subsequent pages. Each parameter may appear only once."},{"name":"created_from","in":"query","schema":{"type":"string","format":"date-time","description":"Inclusive ISO 8601 timestamp with timezone. Date-only values are also accepted at UTC midnight."},"description":"Narrows approved access. Repeat on subsequent pages. Each parameter may appear only once."},{"name":"created_to","in":"query","schema":{"type":"string","format":"date-time","description":"Inclusive ISO 8601 timestamp with timezone. Date-only values are also accepted at UTC midnight."},"description":"Narrows approved access. Repeat on subsequent pages. Each parameter may appear only once."},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time","description":"Inclusive ISO 8601 timestamp with timezone. Date-only values are also accepted at UTC midnight."},"description":"Narrows approved access. Repeat on subsequent pages. Each parameter may appear only once."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time","description":"Inclusive ISO 8601 timestamp with timezone. Date-only values are also accepted at UTC midnight."},"description":"Narrows approved access. Repeat on subsequent pages. Each parameter may appear only once."},{"name":"sort","in":"query","schema":{"type":"string","enum":["created_at","-created_at"],"default":"created_at"},"description":"Narrows approved access. Repeat on subsequent pages. Each parameter may appear only once."}],"responses":{"200":{"description":"Resource summaries and cursor","content":{"application/json":{"schema":{"type":"object","required":["data","next_cursor","has_more"],"properties":{"data":{"type":"array","items":{"type":"object"}},"next_cursor":{"type":"string","nullable":true},"has_more":{"type":"boolean"}}}}}},"400":{"description":"Invalid parameters"},"401":{"description":"Missing, invalid, expired, or revoked key"},"403":{"description":"Missing explicit scope or inactive/restricted key owner"},"429":{"description":"Rate limit exceeded: 120 requests per minute per key"},"500":{"description":"The request could not be completed; nothing is reported as success"}},"tags":["Invoices"]},"post":{"operationId":"invoice_create","summary":"Create a draft invoice","description":"Requires write:invoice_edits. Creates a draft invoice for a customer, optionally linked to one of their jobs, exactly as the office New Invoice form does. Invoice numbers, tax and totals are set by WildPipe. Send it with POST /invoices/{id}/send. company_id is required only for a customer without a company in an organization with several. Retrying with the same Idempotency-Key and identical content returns the original result without repeating the change. Recover a lost response with GET /operations/invoice_create/{key}.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["contact_id","line_items"],"properties":{"contact_id":{"type":"string","format":"uuid"},"company_id":{"type":"string","format":"uuid"},"job_id":{"type":"string","format":"uuid"},"line_items":{"type":"array","minItems":1,"maxItems":200,"items":{"type":"object","additionalProperties":false,"required":["name","quantity","unit_price"],"properties":{"name":{"type":"string","minLength":1,"maxLength":300},"description":{"type":"string","maxLength":5000,"nullable":true},"quantity":{"type":"number","exclusiveMinimum":0,"maximum":100000},"unit_price":{"type":"number","minimum":0,"maximum":1000000,"multipleOf":0.01},"is_taxable":{"type":"boolean","default":true},"discount_type":{"type":"string","enum":["percentage","fixed"]},"discount_value":{"type":"number","minimum":0},"service_id":{"type":"string","format":"uuid"},"product_id":{"type":"string","format":"uuid"},"variant_id":{"type":"string","format":"uuid"}}},"description":"Replaces every line item, in this order. Totals and tax are calculated by WildPipe."},"issue_date":{"type":"string","format":"date"},"due_date":{"type":"string","format":"date"},"notes":{"type":"string","maxLength":10000,"nullable":true},"payment_terms":{"type":"string","maxLength":100,"nullable":true},"po_number":{"type":"string","maxLength":100,"nullable":true},"discount_type":{"type":"string","enum":["percentage","fixed"],"nullable":true},"discount_value":{"type":"number","minimum":0}}}}}},"responses":{"200":{"description":"Original result of an identical retry (replayed true)"},"201":{"description":"Committed; data holds the result and replayed is false"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Invoices"]}},"/invoices/{id}":{"get":{"operationId":"get_invoices","summary":"Retrieve one invoices summary","description":"Requires read:invoices. Uses the same field allowlist as the list endpoint.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Resource summary","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"400":{"description":"Invalid parameters"},"401":{"description":"Missing, invalid, expired, or revoked key"},"403":{"description":"Missing explicit scope or inactive/restricted key owner"},"404":{"description":"Record not found in the authorized organization"},"429":{"description":"Rate limit exceeded: 120 requests per minute per key"},"500":{"description":"The request could not be completed; nothing is reported as success"}},"tags":["Invoices"]},"patch":{"operationId":"invoice_update","summary":"Edit an unpaid invoice","description":"Requires write:invoice_edits. Changes items, due date, notes, terms, PO number or discount on a draft or sent invoice with no money applied. Items on an invoice created from a quote change through a quote revision. Retrying with the same Idempotency-Key and identical content returns the original result without repeating the change. Recover a lost response with GET /operations/invoice_update/{key}.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["expected_updated_at"],"properties":{"expected_updated_at":{"type":"string","format":"date-time","description":"The updated_at you last read. A newer value is refused with 409."},"line_items":{"type":"array","minItems":1,"maxItems":200,"items":{"type":"object","additionalProperties":false,"required":["name","quantity","unit_price"],"properties":{"name":{"type":"string","minLength":1,"maxLength":300},"description":{"type":"string","maxLength":5000,"nullable":true},"quantity":{"type":"number","exclusiveMinimum":0,"maximum":100000},"unit_price":{"type":"number","minimum":0,"maximum":1000000,"multipleOf":0.01},"is_taxable":{"type":"boolean","default":true},"discount_type":{"type":"string","enum":["percentage","fixed"]},"discount_value":{"type":"number","minimum":0},"service_id":{"type":"string","format":"uuid"},"product_id":{"type":"string","format":"uuid"},"variant_id":{"type":"string","format":"uuid"}}},"description":"Replaces every line item, in this order. Totals and tax are calculated by WildPipe."},"due_date":{"type":"string","format":"date","nullable":true},"notes":{"type":"string","maxLength":10000,"nullable":true},"payment_terms":{"type":"string","maxLength":100,"nullable":true},"po_number":{"type":"string","maxLength":100,"nullable":true},"discount_type":{"type":"string","enum":["percentage","fixed"],"nullable":true},"discount_value":{"type":"number","minimum":0}}}}}},"responses":{"200":{"description":"Committed, or the original result of an identical retry"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Invoices"]}},"/payments":{"get":{"operationId":"list_payments","summary":"List payments summaries","description":"Requires read:payments. Explicit returned fields: id,company_id,contact_id,quote_id,amount,method,status,payment_gateway,is_deposit,created_at,updated_at, app_url. Ordered by created_at then id; sort=-created_at reverses both. Search fields: none. Pages are not a point-in-time snapshot, so changes made while you page can affect later pages.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":8192},"description":"Opaque next_cursor from the previous response; repeat the same filters and sort on every page."},{"name":"company_id","in":"query","schema":{"type":"string","format":"uuid"},"description":"Exact direct-record reference match within the authorized organization. Multiple filters use AND, not relationship expansion. Each parameter may appear only once."},{"name":"contact_id","in":"query","schema":{"type":"string","format":"uuid"},"description":"Exact direct-record reference match within the authorized organization. Multiple filters use AND, not relationship expansion. Each parameter may appear only once."},{"name":"quote_id","in":"query","schema":{"type":"string","format":"uuid"},"description":"Exact direct-record reference match within the authorized organization. Multiple filters use AND, not relationship expansion. Each parameter may appear only once."},{"name":"statuses","in":"query","schema":{"type":"string","maxLength":810,"description":"Comma-separated exact stored statuses (OR within the list, AND with other filters). Up to 10 values. Contacts use contact_type; tasks use numeric status_id."},"description":"Narrows approved access. Repeat on subsequent pages. Each parameter may appear only once."},{"name":"amount_min","in":"query","schema":{"type":"number","minimum":0,"maximum":1000000000},"description":"Narrows approved access. Repeat on subsequent pages. Each parameter may appear only once."},{"name":"amount_max","in":"query","schema":{"type":"number","minimum":0,"maximum":1000000000},"description":"Narrows approved access. Repeat on subsequent pages. Each parameter may appear only once."},{"name":"is_deposit","in":"query","schema":{"type":"boolean"},"description":"Narrows approved access. Repeat on subsequent pages. Each parameter may appear only once."},{"name":"created_from","in":"query","schema":{"type":"string","format":"date-time","description":"Inclusive ISO 8601 timestamp with timezone. Date-only values are also accepted at UTC midnight."},"description":"Narrows approved access. Repeat on subsequent pages. Each parameter may appear only once."},{"name":"created_to","in":"query","schema":{"type":"string","format":"date-time","description":"Inclusive ISO 8601 timestamp with timezone. Date-only values are also accepted at UTC midnight."},"description":"Narrows approved access. Repeat on subsequent pages. Each parameter may appear only once."},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time","description":"Inclusive ISO 8601 timestamp with timezone. Date-only values are also accepted at UTC midnight."},"description":"Narrows approved access. Repeat on subsequent pages. Each parameter may appear only once."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time","description":"Inclusive ISO 8601 timestamp with timezone. Date-only values are also accepted at UTC midnight."},"description":"Narrows approved access. Repeat on subsequent pages. Each parameter may appear only once."},{"name":"sort","in":"query","schema":{"type":"string","enum":["created_at","-created_at"],"default":"created_at"},"description":"Narrows approved access. Repeat on subsequent pages. Each parameter may appear only once."}],"responses":{"200":{"description":"Resource summaries and cursor","content":{"application/json":{"schema":{"type":"object","required":["data","next_cursor","has_more"],"properties":{"data":{"type":"array","items":{"type":"object"}},"next_cursor":{"type":"string","nullable":true},"has_more":{"type":"boolean"}}}}}},"400":{"description":"Invalid parameters"},"401":{"description":"Missing, invalid, expired, or revoked key"},"403":{"description":"Missing explicit scope or inactive/restricted key owner"},"429":{"description":"Rate limit exceeded: 120 requests per minute per key"},"500":{"description":"The request could not be completed; nothing is reported as success"}},"tags":["Payments"]},"post":{"operationId":"payment_record","summary":"Record money received outside the card processor","description":"Requires write:payments. Records cash, check or another offline payment exactly like the office Record Payment action and applies it, in order, to the listed unpaid invoices of the same customer and company. Never charges a card. Any amount not needed by the invoices stays unapplied. Commissions, timeline entries and deposit status update after commit. To redeem an invoice's cash/check discount offer, send redeem_cash_discount true, exactly one invoice_ids entry, method cash, check or zelle (when offered), the invoice total you read as expected_regular_total and the full discounted amount; the discount is applied to the invoice and the result includes cash_discount. A changed price or wrong amount is refused. Retrying with the same Idempotency-Key and identical content returns the original result without repeating the change. Recover a lost response with GET /operations/payment_record/{key}.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["contact_id","amount","method"],"properties":{"contact_id":{"type":"string","format":"uuid"},"amount":{"type":"number","exclusiveMinimum":0,"maximum":50000,"multipleOf":0.01},"method":{"type":"string","enum":["cash","check","money_order","ach","bank_transfer","zelle","venmo","other"]},"company_id":{"type":"string","format":"uuid","description":"Required only when the customer has no company."},"invoice_ids":{"type":"array","maxItems":100,"uniqueItems":true,"items":{"type":"string","format":"uuid"}},"quote_id":{"type":"string","format":"uuid"},"notes":{"type":"string","maxLength":2000,"nullable":true},"payment_date":{"type":"string","format":"date-time"},"is_deposit":{"type":"boolean","description":"A deposit requires quote_id."},"redeem_cash_discount":{"type":"boolean","description":"Redeem the invoice's cash/check discount offer. Requires one invoice and expected_regular_total."},"expected_regular_total":{"type":"number","exclusiveMinimum":0,"maximum":1000000,"multipleOf":0.01,"description":"The invoice total you read before the discount. Used only with redeem_cash_discount."}}}}}},"responses":{"200":{"description":"Original result of an identical retry (replayed true)"},"201":{"description":"Committed; data holds the result and replayed is false"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Payments"]}},"/payments/{id}":{"get":{"operationId":"get_payments","summary":"Retrieve one payments summary","description":"Requires read:payments. Uses the same field allowlist as the list endpoint.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Resource summary","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"400":{"description":"Invalid parameters"},"401":{"description":"Missing, invalid, expired, or revoked key"},"403":{"description":"Missing explicit scope or inactive/restricted key owner"},"404":{"description":"Record not found in the authorized organization"},"429":{"description":"Rate limit exceeded: 120 requests per minute per key"},"500":{"description":"The request could not be completed; nothing is reported as success"}},"tags":["Payments"]},"patch":{"operationId":"payment_update","summary":"Correct an offline payment","description":"Requires write:payment_edits. Changes the notes or method of a cash, check or other offline payment recorded by hand. Card and processor payments, disputed payments and payments that redeemed a cash discount are refused. Retrying with the same Idempotency-Key and identical content returns the original result without repeating the change. Recover a lost response with GET /operations/payment_update/{key}.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["expected_updated_at"],"properties":{"expected_updated_at":{"type":"string","format":"date-time","description":"The updated_at you last read. A newer value is refused with 409."},"notes":{"type":"string","maxLength":2000,"nullable":true},"method":{"type":"string","enum":["cash","check","money_order","ach","bank_transfer","zelle","venmo","other"]}}}}}},"responses":{"200":{"description":"Committed, or the original result of an identical retry"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Payments"]},"delete":{"operationId":"payment_delete","summary":"Delete an offline payment recorded in error","description":"Requires write:payment_edits. Deletes a cash, check or other offline payment recorded by hand, as the office Delete Payment action does: invoices it paid return to their unpaid balance. Card and processor payments must be refunded instead, and disputed payments are refused. Retrying with the same Idempotency-Key and identical content returns the original result without repeating the change. Recover a lost response with GET /operations/payment_delete/{key}.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}},{"name":"expected_updated_at","in":"query","required":true,"schema":{"type":"string","format":"date-time","description":"The updated_at you last read. A newer value is refused with 409."}}],"responses":{"200":{"description":"Committed, or the original result of an identical retry"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Payments"]}},"/leads":{"get":{"operationId":"list_leads","summary":"List leads summaries","description":"Requires read:leads. Explicit returned fields: id,company_id,contact_id,job_id,quote_id,source,status,follow_up_date,created_at,updated_at, app_url. Ordered by created_at then id; sort=-created_at reverses both. Search fields: none. Pages are not a point-in-time snapshot, so changes made while you page can affect later pages.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":8192},"description":"Opaque next_cursor from the previous response; repeat the same filters and sort on every page."},{"name":"company_id","in":"query","schema":{"type":"string","format":"uuid"},"description":"Exact direct-record reference match within the authorized organization. Multiple filters use AND, not relationship expansion. Each parameter may appear only once."},{"name":"contact_id","in":"query","schema":{"type":"string","format":"uuid"},"description":"Exact direct-record reference match within the authorized organization. Multiple filters use AND, not relationship expansion. Each parameter may appear only once."},{"name":"job_id","in":"query","schema":{"type":"string","format":"uuid"},"description":"Exact direct-record reference match within the authorized organization. Multiple filters use AND, not relationship expansion. Each parameter may appear only once."},{"name":"quote_id","in":"query","schema":{"type":"string","format":"uuid"},"description":"Exact direct-record reference match within the authorized organization. Multiple filters use AND, not relationship expansion. Each parameter may appear only once."},{"name":"statuses","in":"query","schema":{"type":"string","maxLength":810,"description":"Comma-separated exact stored statuses (OR within the list, AND with other filters). Up to 10 values. Contacts use contact_type; tasks use numeric status_id."},"description":"Narrows approved access. Repeat on subsequent pages. Each parameter may appear only once."},{"name":"source","in":"query","schema":{"type":"string","maxLength":200},"description":"Narrows approved access. Repeat on subsequent pages. Each parameter may appear only once."},{"name":"follow_up_from","in":"query","schema":{"type":"string","format":"date-time","description":"Inclusive ISO 8601 timestamp with timezone. Date-only values are also accepted at UTC midnight."},"description":"Narrows approved access. Repeat on subsequent pages. Each parameter may appear only once."},{"name":"follow_up_to","in":"query","schema":{"type":"string","format":"date-time","description":"Inclusive ISO 8601 timestamp with timezone. Date-only values are also accepted at UTC midnight."},"description":"Narrows approved access. Repeat on subsequent pages. Each parameter may appear only once."},{"name":"created_from","in":"query","schema":{"type":"string","format":"date-time","description":"Inclusive ISO 8601 timestamp with timezone. Date-only values are also accepted at UTC midnight."},"description":"Narrows approved access. Repeat on subsequent pages. Each parameter may appear only once."},{"name":"created_to","in":"query","schema":{"type":"string","format":"date-time","description":"Inclusive ISO 8601 timestamp with timezone. Date-only values are also accepted at UTC midnight."},"description":"Narrows approved access. Repeat on subsequent pages. Each parameter may appear only once."},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time","description":"Inclusive ISO 8601 timestamp with timezone. Date-only values are also accepted at UTC midnight."},"description":"Narrows approved access. Repeat on subsequent pages. Each parameter may appear only once."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time","description":"Inclusive ISO 8601 timestamp with timezone. Date-only values are also accepted at UTC midnight."},"description":"Narrows approved access. Repeat on subsequent pages. Each parameter may appear only once."},{"name":"sort","in":"query","schema":{"type":"string","enum":["created_at","-created_at"],"default":"created_at"},"description":"Narrows approved access. Repeat on subsequent pages. Each parameter may appear only once."}],"responses":{"200":{"description":"Resource summaries and cursor","content":{"application/json":{"schema":{"type":"object","required":["data","next_cursor","has_more"],"properties":{"data":{"type":"array","items":{"type":"object"}},"next_cursor":{"type":"string","nullable":true},"has_more":{"type":"boolean"}}}}}},"400":{"description":"Invalid parameters"},"401":{"description":"Missing, invalid, expired, or revoked key"},"403":{"description":"Missing explicit scope or inactive/restricted key owner"},"429":{"description":"Rate limit exceeded: 120 requests per minute per key"},"500":{"description":"The request could not be completed; nothing is reported as success"}},"tags":["Leads"]},"post":{"operationId":"create_lead","summary":"Idempotently create a new lead","description":"Requires write:leads. Requires an organization-owned contact; company defaults to its company or must be supplied explicitly for an unbranded contact. A different company from a branded contact is rejected. Lead, subscribed event, audit and receipt commit together. Does not create bookings or change communication consent.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["contact_id"],"additionalProperties":false,"properties":{"contact_id":{"type":"string","format":"uuid"},"company_id":{"type":"string","format":"uuid","nullable":true},"source":{"type":"string","maxLength":200,"nullable":true},"notes":{"type":"string","nullable":true}}}}}},"responses":{"200":{"description":"Stored result replayed without another mutation"},"201":{"description":"Lead and subscribed outbound event committed atomically"},"400":{"description":"Invalid parameters"},"401":{"description":"Missing, invalid, expired, or revoked key"},"403":{"description":"Missing explicit scope or inactive/restricted key owner"},"409":{"description":"Event/idempotency key reused with different exact body bytes"},"415":{"description":"application/json required"},"422":{"description":"Invalid input or mapping"},"429":{"description":"Rate limit exceeded: 120 requests per minute per key"},"500":{"description":"The request could not be completed; nothing is reported as success"},"503":{"description":"Transaction unavailable; retry the same identity and bytes"}},"tags":["Leads"]}},"/leads/{id}":{"get":{"operationId":"get_leads","summary":"Retrieve one leads summary","description":"Requires read:leads. Uses the same field allowlist as the list endpoint.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Resource summary","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"400":{"description":"Invalid parameters"},"401":{"description":"Missing, invalid, expired, or revoked key"},"403":{"description":"Missing explicit scope or inactive/restricted key owner"},"404":{"description":"Record not found in the authorized organization"},"429":{"description":"Rate limit exceeded: 120 requests per minute per key"},"500":{"description":"The request could not be completed; nothing is reported as success"}},"tags":["Leads"]},"patch":{"operationId":"update_leads_metadata","summary":"Update lead source, notes or follow-up date","description":"Requires write:leads. Only notes, source and follow_up_date may change. Omitted fields are preserved; null clears a field. Follow-up dates must be real UTC timestamps in YYYY-MM-DDTHH:mm:ssZ or YYYY-MM-DDTHH:mm:ss.SSSZ format (years 0001–9999). This sets a follow-up reminder, not an appointment. No identity, company, consent, status, booking or financial changes. Updates replace values (not append); distinct request keys are last-writer-wins. Repeating the same key/target/exact body returns the original receipt without reapplying an older update.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"minProperties":1,"properties":{"notes":{"type":"string","nullable":true,"maxLength":10000},"source":{"type":"string","nullable":true,"maxLength":200},"follow_up_date":{"type":"string","format":"date-time","nullable":true,"description":"UTC only, seconds required, optional exactly three fractional digits. Null clears the follow-up.","example":"2026-10-01T14:30:00Z"}}}}}},"responses":{"200":{"description":"Atomic update or original replay: data contains id, company_id and updated_fields; replayed is boolean. No note contents returned."},"400":{"description":"Invalid parameters"},"401":{"description":"Missing, invalid, expired, or revoked key"},"403":{"description":"Missing explicit scope or inactive/restricted key owner"},"409":{"description":"Key reused with different body or target within this resource update family"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or body larger than 32 KiB"},"429":{"description":"Rate limit exceeded: 120 requests per minute per key"},"500":{"description":"The request could not be completed; nothing is reported as success"},"503":{"description":"Retry same target, key and exact bytes; no partial transaction is committed"}},"tags":["Leads"]}},"/services":{"get":{"operationId":"list_services","summary":"List services summaries","description":"Requires read:services. Explicit returned fields: id,company_ids,name,description,duration,billing_type,initial_price,recurring_price,billing_frequency,requires_inspection,followup_quote_expected,created_at,updated_at. Ordered by created_at then id; sort=-created_at reverses both. Search fields: name, description. Pages are not a point-in-time snapshot, so changes made while you page can affect later pages.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":8192},"description":"Opaque next_cursor from the previous response; repeat the same filters and sort on every page."},{"name":"search","in":"query","schema":{"type":"string","maxLength":200},"description":"Literal case-insensitive substring across this resource’s searchable summary fields; punctuation is data, not filter syntax. Names are matched per field, not concatenated."},{"name":"created_from","in":"query","schema":{"type":"string","format":"date-time","description":"Inclusive ISO 8601 timestamp with timezone. Date-only values are also accepted at UTC midnight."},"description":"Narrows approved access. Repeat on subsequent pages. Each parameter may appear only once."},{"name":"created_to","in":"query","schema":{"type":"string","format":"date-time","description":"Inclusive ISO 8601 timestamp with timezone. Date-only values are also accepted at UTC midnight."},"description":"Narrows approved access. Repeat on subsequent pages. Each parameter may appear only once."},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time","description":"Inclusive ISO 8601 timestamp with timezone. Date-only values are also accepted at UTC midnight."},"description":"Narrows approved access. Repeat on subsequent pages. Each parameter may appear only once."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time","description":"Inclusive ISO 8601 timestamp with timezone. Date-only values are also accepted at UTC midnight."},"description":"Narrows approved access. Repeat on subsequent pages. Each parameter may appear only once."},{"name":"sort","in":"query","schema":{"type":"string","enum":["created_at","-created_at"],"default":"created_at"},"description":"Narrows approved access. Repeat on subsequent pages. Each parameter may appear only once."}],"responses":{"200":{"description":"Resource summaries and cursor","content":{"application/json":{"schema":{"type":"object","required":["data","next_cursor","has_more"],"properties":{"data":{"type":"array","items":{"type":"object"}},"next_cursor":{"type":"string","nullable":true},"has_more":{"type":"boolean"}}}}}},"400":{"description":"Invalid parameters"},"401":{"description":"Missing, invalid, expired, or revoked key"},"403":{"description":"Missing explicit scope or inactive/restricted key owner"},"429":{"description":"Rate limit exceeded: 120 requests per minute per key"},"500":{"description":"The request could not be completed; nothing is reported as success"}},"tags":["Services"]},"post":{"operationId":"service_create","summary":"Add a one-time service to the catalog","description":"Requires write:catalog. Creates a one-time service. Recurring plans, variants and pricing rules are set up in WildPipe. Requires unrestricted company access. Retrying with the same Idempotency-Key and identical content returns the original result without repeating the change. Recover a lost response with GET /operations/service_create/{key}.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["name"],"properties":{"name":{"type":"string","minLength":1,"maxLength":200},"description":{"type":"string","maxLength":10000,"nullable":true},"service_warranty":{"type":"string","maxLength":10000,"nullable":true},"duration":{"type":"integer","minimum":1,"maximum":1440,"description":"On-site minutes"},"initial_price":{"type":"number","minimum":0,"maximum":1000000,"nullable":true},"customer_schedulable":{"type":"boolean"},"exclude_from_ai":{"type":"boolean"},"requires_inspection":{"type":"boolean"},"followup_quote_expected":{"type":"boolean"},"target_pests":{"type":"array","maxItems":50,"items":{"type":"string","minLength":1,"maxLength":80}},"company_ids":{"type":"array","maxItems":100,"uniqueItems":true,"items":{"type":"string","format":"uuid"},"description":"Companies that offer it; empty means every company."}}}}}},"responses":{"200":{"description":"Original result of an identical retry (replayed true)"},"201":{"description":"Committed; data holds the result and replayed is false"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Services"]}},"/services/{id}":{"get":{"operationId":"get_services","summary":"Retrieve one services summary","description":"Requires read:services. Uses the same field allowlist as the list endpoint.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Resource summary","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"400":{"description":"Invalid parameters"},"401":{"description":"Missing, invalid, expired, or revoked key"},"403":{"description":"Missing explicit scope or inactive/restricted key owner"},"404":{"description":"Record not found in the authorized organization"},"429":{"description":"Rate limit exceeded: 120 requests per minute per key"},"500":{"description":"The request could not be completed; nothing is reported as success"}},"tags":["Services"]},"patch":{"operationId":"service_update","summary":"Change a catalog service","description":"Requires write:catalog. Updates only the fields you send. recurring_price applies to existing recurring plans only. Existing quotes and invoices keep their prices. Requires unrestricted company access. Retrying with the same Idempotency-Key and identical content returns the original result without repeating the change. Recover a lost response with GET /operations/service_update/{key}.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["expected_updated_at"],"properties":{"expected_updated_at":{"type":"string","format":"date-time","description":"The updated_at you last read. A newer value is refused with 409."},"name":{"type":"string","minLength":1,"maxLength":200},"description":{"type":"string","maxLength":10000,"nullable":true},"service_warranty":{"type":"string","maxLength":10000,"nullable":true},"duration":{"type":"integer","minimum":1,"maximum":1440,"description":"On-site minutes"},"initial_price":{"type":"number","minimum":0,"maximum":1000000,"nullable":true},"customer_schedulable":{"type":"boolean"},"exclude_from_ai":{"type":"boolean"},"requires_inspection":{"type":"boolean"},"followup_quote_expected":{"type":"boolean"},"target_pests":{"type":"array","maxItems":50,"items":{"type":"string","minLength":1,"maxLength":80}},"company_ids":{"type":"array","maxItems":100,"uniqueItems":true,"items":{"type":"string","format":"uuid"},"description":"Companies that offer it; empty means every company."},"recurring_price":{"type":"number","minimum":0,"maximum":1000000,"nullable":true}}}}}},"responses":{"200":{"description":"Committed, or the original result of an identical retry"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Services"]},"delete":{"operationId":"service_delete","summary":"Delete a catalog service","description":"Requires write:catalog. Removes the service and its variants, as the office delete does. Existing quotes and invoices keep their line items. Refused with 409 when other records still depend on it. Requires unrestricted company access. Retrying with the same Idempotency-Key and identical content returns the original result without repeating the change. Recover a lost response with GET /operations/service_delete/{key}.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}},{"name":"expected_updated_at","in":"query","required":true,"schema":{"type":"string","format":"date-time","description":"The updated_at you last read. A newer value is refused with 409."}}],"responses":{"200":{"description":"Committed, or the original result of an identical retry"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Services"]}},"/products":{"get":{"operationId":"list_products","summary":"List products summaries","description":"Requires read:products. Explicit returned fields: id,company_ids,name,description,base_price,image_urls,created_at,updated_at. Ordered by created_at then id; sort=-created_at reverses both. Search fields: name, description. Pages are not a point-in-time snapshot, so changes made while you page can affect later pages.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":8192},"description":"Opaque next_cursor from the previous response; repeat the same filters and sort on every page."},{"name":"search","in":"query","schema":{"type":"string","maxLength":200},"description":"Literal case-insensitive substring across this resource’s searchable summary fields; punctuation is data, not filter syntax. Names are matched per field, not concatenated."},{"name":"created_from","in":"query","schema":{"type":"string","format":"date-time","description":"Inclusive ISO 8601 timestamp with timezone. Date-only values are also accepted at UTC midnight."},"description":"Narrows approved access. Repeat on subsequent pages. Each parameter may appear only once."},{"name":"created_to","in":"query","schema":{"type":"string","format":"date-time","description":"Inclusive ISO 8601 timestamp with timezone. Date-only values are also accepted at UTC midnight."},"description":"Narrows approved access. Repeat on subsequent pages. Each parameter may appear only once."},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time","description":"Inclusive ISO 8601 timestamp with timezone. Date-only values are also accepted at UTC midnight."},"description":"Narrows approved access. Repeat on subsequent pages. Each parameter may appear only once."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time","description":"Inclusive ISO 8601 timestamp with timezone. Date-only values are also accepted at UTC midnight."},"description":"Narrows approved access. Repeat on subsequent pages. Each parameter may appear only once."},{"name":"sort","in":"query","schema":{"type":"string","enum":["created_at","-created_at"],"default":"created_at"},"description":"Narrows approved access. Repeat on subsequent pages. Each parameter may appear only once."}],"responses":{"200":{"description":"Resource summaries and cursor","content":{"application/json":{"schema":{"type":"object","required":["data","next_cursor","has_more"],"properties":{"data":{"type":"array","items":{"type":"object"}},"next_cursor":{"type":"string","nullable":true},"has_more":{"type":"boolean"}}}}}},"400":{"description":"Invalid parameters"},"401":{"description":"Missing, invalid, expired, or revoked key"},"403":{"description":"Missing explicit scope or inactive/restricted key owner"},"429":{"description":"Rate limit exceeded: 120 requests per minute per key"},"500":{"description":"The request could not be completed; nothing is reported as success"}},"tags":["Products"]},"post":{"operationId":"product_create","summary":"Add a product to the catalog","description":"Requires write:catalog. Creates a product. Option groups and variants are configured in WildPipe. Requires unrestricted company access. Retrying with the same Idempotency-Key and identical content returns the original result without repeating the change. Recover a lost response with GET /operations/product_create/{key}.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["name"],"properties":{"name":{"type":"string","minLength":1,"maxLength":200},"description":{"type":"string","maxLength":10000,"nullable":true},"manufacturer_warranty":{"type":"string","maxLength":10000,"nullable":true},"base_price":{"type":"number","minimum":0,"maximum":1000000,"nullable":true},"exclude_from_ai":{"type":"boolean"},"company_ids":{"type":"array","maxItems":100,"uniqueItems":true,"items":{"type":"string","format":"uuid"},"description":"Companies that offer it; empty means every company."}}}}}},"responses":{"200":{"description":"Original result of an identical retry (replayed true)"},"201":{"description":"Committed; data holds the result and replayed is false"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Products"]}},"/products/{id}":{"get":{"operationId":"get_products","summary":"Retrieve one products summary","description":"Requires read:products. Uses the same field allowlist as the list endpoint.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Resource summary","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"400":{"description":"Invalid parameters"},"401":{"description":"Missing, invalid, expired, or revoked key"},"403":{"description":"Missing explicit scope or inactive/restricted key owner"},"404":{"description":"Record not found in the authorized organization"},"429":{"description":"Rate limit exceeded: 120 requests per minute per key"},"500":{"description":"The request could not be completed; nothing is reported as success"}},"tags":["Products"]},"patch":{"operationId":"product_update","summary":"Change a catalog product","description":"Requires write:catalog. Updates only the fields you send. Requires unrestricted company access. Retrying with the same Idempotency-Key and identical content returns the original result without repeating the change. Recover a lost response with GET /operations/product_update/{key}.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["expected_updated_at"],"properties":{"expected_updated_at":{"type":"string","format":"date-time","description":"The updated_at you last read. A newer value is refused with 409."},"name":{"type":"string","minLength":1,"maxLength":200},"description":{"type":"string","maxLength":10000,"nullable":true},"manufacturer_warranty":{"type":"string","maxLength":10000,"nullable":true},"base_price":{"type":"number","minimum":0,"maximum":1000000,"nullable":true},"exclude_from_ai":{"type":"boolean"},"company_ids":{"type":"array","maxItems":100,"uniqueItems":true,"items":{"type":"string","format":"uuid"},"description":"Companies that offer it; empty means every company."}}}}}},"responses":{"200":{"description":"Committed, or the original result of an identical retry"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Products"]},"delete":{"operationId":"product_delete","summary":"Delete a catalog product","description":"Requires write:catalog. Removes the product and its variants. Refused with 409 when other records still depend on it. Requires unrestricted company access. Retrying with the same Idempotency-Key and identical content returns the original result without repeating the change. Recover a lost response with GET /operations/product_delete/{key}.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}},{"name":"expected_updated_at","in":"query","required":true,"schema":{"type":"string","format":"date-time","description":"The updated_at you last read. A newer value is refused with 409."}}],"responses":{"200":{"description":"Committed, or the original result of an identical retry"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Products"]}},"/companies":{"get":{"operationId":"list_companies","summary":"List companies summaries","description":"Requires read:companies. Explicit returned fields: id,name,public_name,timezone,created_at,updated_at. Ordered by created_at then id; sort=-created_at reverses both. Search fields: name, public_name. Pages are not a point-in-time snapshot, so changes made while you page can affect later pages.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":8192},"description":"Opaque next_cursor from the previous response; repeat the same filters and sort on every page."},{"name":"search","in":"query","schema":{"type":"string","maxLength":200},"description":"Literal case-insensitive substring across this resource’s searchable summary fields; punctuation is data, not filter syntax. Names are matched per field, not concatenated."},{"name":"created_from","in":"query","schema":{"type":"string","format":"date-time","description":"Inclusive ISO 8601 timestamp with timezone. Date-only values are also accepted at UTC midnight."},"description":"Narrows approved access. Repeat on subsequent pages. Each parameter may appear only once."},{"name":"created_to","in":"query","schema":{"type":"string","format":"date-time","description":"Inclusive ISO 8601 timestamp with timezone. Date-only values are also accepted at UTC midnight."},"description":"Narrows approved access. Repeat on subsequent pages. Each parameter may appear only once."},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time","description":"Inclusive ISO 8601 timestamp with timezone. Date-only values are also accepted at UTC midnight."},"description":"Narrows approved access. Repeat on subsequent pages. Each parameter may appear only once."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time","description":"Inclusive ISO 8601 timestamp with timezone. Date-only values are also accepted at UTC midnight."},"description":"Narrows approved access. Repeat on subsequent pages. Each parameter may appear only once."},{"name":"sort","in":"query","schema":{"type":"string","enum":["created_at","-created_at"],"default":"created_at"},"description":"Narrows approved access. Repeat on subsequent pages. Each parameter may appear only once."}],"responses":{"200":{"description":"Resource summaries and cursor","content":{"application/json":{"schema":{"type":"object","required":["data","next_cursor","has_more"],"properties":{"data":{"type":"array","items":{"type":"object"}},"next_cursor":{"type":"string","nullable":true},"has_more":{"type":"boolean"}}}}}},"400":{"description":"Invalid parameters"},"401":{"description":"Missing, invalid, expired, or revoked key"},"403":{"description":"Missing explicit scope or inactive/restricted key owner"},"429":{"description":"Rate limit exceeded: 120 requests per minute per key"},"500":{"description":"The request could not be completed; nothing is reported as success"}},"tags":["Companies"]}},"/companies/{id}":{"get":{"operationId":"get_companies","summary":"Retrieve one companies summary","description":"Requires read:companies. Uses the same field allowlist as the list endpoint.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Resource summary","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"400":{"description":"Invalid parameters"},"401":{"description":"Missing, invalid, expired, or revoked key"},"403":{"description":"Missing explicit scope or inactive/restricted key owner"},"404":{"description":"Record not found in the authorized organization"},"429":{"description":"Rate limit exceeded: 120 requests per minute per key"},"500":{"description":"The request could not be completed; nothing is reported as success"}},"tags":["Companies"]}},"/services/{id}/variants":{"get":{"operationId":"list_services_variants","summary":"List variants for one service","description":"Requires read:services. Parent must be in the organization and accessible to the key's company scope; shared catalog items remain accessible. Returns only id,name,description,price,initial_price,recurring_price,sku,warranty_terms,created_at,updated_at. Internal costs, file URLs and ambiguous dual-parent variants are excluded. Ordered by UUID, not display order. No snapshot isolation across pages.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string"},"description":"Opaque next_cursor, bound to this resource and parent ID."}],"responses":{"200":{"description":"data array, has_more boolean, next_cursor string or null; empty data for an accessible parent with no variants"},"400":{"description":"Invalid parameters"},"401":{"description":"Missing, invalid, expired, or revoked key"},"403":{"description":"Missing explicit scope or inactive/restricted key owner"},"404":{"description":"Parent not found in authorized scope"},"429":{"description":"Rate limit exceeded: 120 requests per minute per key"},"500":{"description":"The request could not be completed; nothing is reported as success"},"503":{"description":"Catalog lookup unavailable; no empty-success fallback"}},"tags":["Services"]}},"/products/{id}/variants":{"get":{"operationId":"list_products_variants","summary":"List variants for one product","description":"Requires read:products. Parent must be in the organization and accessible to the key's company scope; shared catalog items remain accessible. Returns only id,name,description,price,initial_price,recurring_price,sku,warranty_terms,created_at,updated_at. Internal costs, file URLs and ambiguous dual-parent variants are excluded. Ordered by UUID, not display order. No snapshot isolation across pages.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string"},"description":"Opaque next_cursor, bound to this resource and parent ID."}],"responses":{"200":{"description":"data array, has_more boolean, next_cursor string or null; empty data for an accessible parent with no variants"},"400":{"description":"Invalid parameters"},"401":{"description":"Missing, invalid, expired, or revoked key"},"403":{"description":"Missing explicit scope or inactive/restricted key owner"},"404":{"description":"Parent not found in authorized scope"},"429":{"description":"Rate limit exceeded: 120 requests per minute per key"},"500":{"description":"The request could not be completed; nothing is reported as success"},"503":{"description":"Catalog lookup unavailable; no empty-success fallback"}},"tags":["Products"]}},"/receipts/{resource}/{key}":{"get":{"operationId":"get_mutation_receipt","summary":"Find a committed contact or lead API request receipt","description":"Requires write:contacts for contacts/contacts-updates or write:leads for leads/leads-updates, and the same issuing API key. contacts-updates and leads-updates return the original PATCH receipt, not current values. Current company access is rechecked. Does not return inbound webhook receipts. A missing receipt is not proof that an in-flight request will fail; retry the original request with the same key and exact bytes.","parameters":[{"name":"resource","in":"path","required":true,"schema":{"type":"string","enum":["contacts","contacts-updates","leads","leads-updates"]}},{"name":"key","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"responses":{"200":{"description":"Original data and committed_at timestamp"},"400":{"description":"Invalid parameters"},"401":{"description":"Missing, invalid, expired, or revoked key"},"403":{"description":"Missing explicit scope or inactive/restricted key owner"},"404":{"description":"No committed receipt found for this key/resource"},"429":{"description":"Rate limit exceeded: 120 requests per minute per key"},"500":{"description":"The request could not be completed; nothing is reported as success"},"503":{"description":"Receipt lookup unavailable"}},"tags":["Receipts"]}},"/emails":{"post":{"operationId":"submit_email","summary":"Submit one customer email with a durable request identity","description":"Requires write:emails. Sends plain text from the company’s own email address to the matching contact’s saved email only. Existing email permission, suppression, unsubscribe and company branding apply. No HTML, recipient/sender override, CC/BCC, attachments or scheduling. Any uncertain outcome requires review, never a new-key resend.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["company_id","contact_id","subject","message"],"properties":{"company_id":{"type":"string","format":"uuid"},"contact_id":{"type":"string","format":"uuid"},"subject":{"type":"string","minLength":1,"maxLength":200,"pattern":"^[^\\r\\n\\u0000]+$"},"message":{"type":"string","minLength":1,"maxLength":10000}}}}}},"responses":{"200":{"description":"Submitted and saved; not proof of inbox delivery"},"202":{"description":"Attempting or needs_reconciliation; never automatically resent"},"400":{"description":"Invalid parameters"},"401":{"description":"Missing, invalid, expired, or revoked key"},"403":{"description":"Missing explicit scope or inactive/restricted key owner"},"409":{"description":"Same key with different exact body bytes"},"415":{"description":"application/json required"},"422":{"description":"Invalid input or saved email"},"429":{"description":"Rate limit exceeded: 120 requests per minute per key"},"500":{"description":"The request could not be completed; nothing is reported as success"},"503":{"description":"Operation unavailable; retry only the same identity and bytes"}},"tags":["Email"]}},"/emails/{key}":{"get":{"operationId":"get_email_operation","summary":"Read this key’s customer email submission receipt","description":"Requires write:emails and current company/contact access. Returns id, state, email_id, created_at and finished_at only. An attempt older than two minutes is reported as needs_reconciliation; it is never automatically resent.","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"responses":{"200":{"description":"Submitted and saved; not proof of inbox delivery"},"202":{"description":"Attempting or needs_reconciliation; never automatically resent"},"400":{"description":"Invalid parameters"},"401":{"description":"Missing, invalid, expired, or revoked key"},"403":{"description":"Missing explicit scope or inactive/restricted key owner"},"404":{"description":"No operation found; an in-flight request may still commit"},"409":{"description":"Same key with different exact body bytes"},"415":{"description":"application/json required"},"422":{"description":"Invalid input or saved email"},"429":{"description":"Rate limit exceeded: 120 requests per minute per key"},"500":{"description":"The request could not be completed; nothing is reported as success"},"503":{"description":"Operation unavailable; retry only the same identity and bytes"}},"tags":["Email"]}},"/sms":{"post":{"operationId":"submit_sms","summary":"Submit one consent-aware SMS with durable request identity","description":"Requires write:sms. Explicit matching company/contact and service or marketing classification required. Sends only to the saved US/Canada primary phone. No schedule, media, sender override or consent bypass. An existing request is never reissued after failure or process termination. Uncertain/refused outcomes need human review; do not retry with a new key.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["company_id","contact_id","message","message_class"],"properties":{"company_id":{"type":"string","format":"uuid"},"contact_id":{"type":"string","format":"uuid"},"message":{"type":"string","minLength":1,"maxLength":1600},"message_class":{"type":"string","enum":["service","marketing"]}}}}}},"responses":{"200":{"description":"Submitted to provider and saved; not proof of handset delivery"},"202":{"description":"Attempting or needs_reconciliation; never automatically resubmitted"},"400":{"description":"Invalid parameters"},"401":{"description":"Missing, invalid, expired, or revoked key"},"403":{"description":"Missing explicit scope or inactive/restricted key owner"},"409":{"description":"Same key with different exact body bytes"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or unsupported contact phone"},"429":{"description":"Rate limit exceeded: 120 requests per minute per key"},"500":{"description":"The request could not be completed; nothing is reported as success"},"503":{"description":"Operation unavailable; retry only the same identity and bytes"}},"tags":["SMS"]}},"/sms/{key}":{"get":{"operationId":"get_sms_operation","summary":"Read this API key’s SMS submission outcome","description":"Requires write:sms and current company/contact access. Returns operation id, state, sms_id and timestamps only. Attempting older than two minutes is reported as needs_reconciliation, not retried. This is submission evidence, not delivery tracking.","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"responses":{"200":{"description":"Submitted to provider and saved; not proof of handset delivery"},"202":{"description":"Attempting or needs_reconciliation; never automatically resubmitted"},"400":{"description":"Invalid parameters"},"401":{"description":"Missing, invalid, expired, or revoked key"},"403":{"description":"Missing explicit scope or inactive/restricted key owner"},"404":{"description":"No operation found; an in-flight request may still commit"},"409":{"description":"Same key with different exact body bytes"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or unsupported contact phone"},"429":{"description":"Rate limit exceeded: 120 requests per minute per key"},"500":{"description":"The request could not be completed; nothing is reported as success"},"503":{"description":"Operation unavailable; retry only the same identity and bytes"}},"tags":["SMS"]}},"/inbound-webhooks":{"get":{"operationId":"list_inbound_webhooks","summary":"List up to 100 newest inbound endpoints owned by this key","description":"Requires the matching action write scope; never returns secrets.","responses":{"200":{"description":"Endpoint configurations"},"400":{"description":"Invalid parameters"},"401":{"description":"Missing, invalid, expired, or revoked key"},"403":{"description":"Missing explicit scope or inactive/restricted key owner"},"429":{"description":"Rate limit exceeded: 120 requests per minute per key"},"500":{"description":"The request could not be completed; nothing is reported as success"}},"tags":["Inbound Webhooks"]},"post":{"operationId":"create_inbound_webhook","summary":"Create a signed contact or lead intake endpoint","description":"Requires write:contacts or write:leads matching the selected action. At most 50 active endpoints per key. Returns the secret once. Mapping is immutable; create a replacement endpoint to change it.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name"],"additionalProperties":false,"properties":{"action":{"type":"string","enum":["create_contact","create_lead"],"default":"create_contact"},"name":{"type":"string","minLength":1,"maxLength":100},"company_id":{"type":"string","format":"uuid","nullable":true},"mapping":{"type":"object","additionalProperties":{"type":"string"},"description":"Allowlisted action field to dotted source-field path; empty uses standard data envelope."}}}}}},"responses":{"201":{"description":"Endpoint and one-time signing_secret"},"400":{"description":"Invalid parameters"},"401":{"description":"Missing, invalid, expired, or revoked key"},"403":{"description":"Missing explicit scope or inactive/restricted key owner"},"422":{"description":"Invalid mapping/company or endpoint limit reached"},"429":{"description":"Rate limit exceeded: 120 requests per minute per key"},"500":{"description":"The request could not be completed; nothing is reported as success"}},"tags":["Inbound Webhooks"]}},"/inbound-webhooks/{id}":{"get":{"operationId":"get_inbound_webhook","summary":"Get key-owned configuration without secret","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Endpoint configuration array; unavailable endpoint returns 404"},"400":{"description":"Invalid parameters"},"401":{"description":"Missing, invalid, expired, or revoked key"},"403":{"description":"Missing explicit scope or inactive/restricted key owner"},"429":{"description":"Rate limit exceeded: 120 requests per minute per key"},"500":{"description":"The request could not be completed; nothing is reported as success"}},"tags":["Inbound Webhooks"]},"delete":{"operationId":"revoke_inbound_webhook","summary":"Permanently disable intake without deleting receipts","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Endpoint revoked"},"400":{"description":"Invalid parameters"},"401":{"description":"Missing, invalid, expired, or revoked key"},"403":{"description":"Missing explicit scope or inactive/restricted key owner"},"422":{"description":"Endpoint unavailable"},"429":{"description":"Rate limit exceeded: 120 requests per minute per key"},"500":{"description":"The request could not be completed; nothing is reported as success"}},"tags":["Inbound Webhooks"]}},"/inbound-webhooks/{id}/rotate-secret":{"post":{"operationId":"rotate_inbound_secret","summary":"Rotate secret immediately, returning replacement once","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Replacement signing_secret; previous secret no longer accepted"},"400":{"description":"Invalid parameters"},"401":{"description":"Missing, invalid, expired, or revoked key"},"403":{"description":"Missing explicit scope or inactive/restricted key owner"},"422":{"description":"Endpoint unavailable"},"429":{"description":"Rate limit exceeded: 120 requests per minute per key"},"500":{"description":"The request could not be completed; nothing is reported as success"}},"tags":["Inbound Webhooks"]}},"/inbound/contacts/{id}":{"servers":[{"url":"https://api.wildpipe.com"}],"post":{"operationId":"receive_contact_webhook","summary":"Signed contact webhook; no API key header required","security":[{"InboundSignature":[]}],"description":"HMAC-SHA256 signs timestamp.endpointUUID.eventId.exactBodyBytes. Header t=<unix-seconds>,v1=<hex>. Five-minute tolerance, 64 KiB body limit. Same event and exact body replay the original result; changed bytes conflict. The key, its issuer and the endpoint are re-authorized when each event is processed.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-WildPipe-Event-Id","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","description":"Standard: {data: contact}. Configured mappings accept provider objects."}}}},"responses":{"200":{"description":"Stored result replayed without another mutation"},"201":{"description":"Contact and outbound event committed atomically"},"400":{"description":"Invalid parameters"},"401":{"description":"Missing, invalid, expired, or revoked key"},"403":{"description":"Missing explicit scope or inactive/restricted key owner"},"409":{"description":"Event/idempotency key reused with different exact body bytes"},"422":{"description":"Invalid input or mapping"},"429":{"description":"Rate limit exceeded: 120 requests per minute per key"},"500":{"description":"The request could not be completed; nothing is reported as success"},"503":{"description":"Transaction unavailable; retry the same identity and bytes"}},"tags":["Inbound Webhooks"]}},"/inbound/leads/{id}":{"servers":[{"url":"https://api.wildpipe.com"}],"post":{"operationId":"receive_lead_webhook","summary":"Signed lead webhook; existing contact required","security":[{"InboundSignature":[]}],"description":"Same timestamp/endpoint/event/raw-body signature as contact intake. Endpoint action must be create_lead; write:leads required on its parent key. Standard data fields: contact_id, company_id, source, notes. Creates the lead exactly as the office does, keeps consent and company rules, and ignores repeats of the same endpoint and event ID.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"X-WildPipe-Event-Id","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","description":"Standard: {data: contact}. Configured mappings accept provider objects."}}}},"responses":{"200":{"description":"Stored result replayed without another mutation"},"201":{"description":"Contact and outbound event committed atomically"},"400":{"description":"Invalid parameters"},"401":{"description":"Missing, invalid, expired, or revoked key"},"403":{"description":"Missing explicit scope or inactive/restricted key owner"},"409":{"description":"Event/idempotency key reused with different exact body bytes"},"422":{"description":"Invalid input or mapping"},"429":{"description":"Rate limit exceeded: 120 requests per minute per key"},"500":{"description":"The request could not be completed; nothing is reported as success"},"503":{"description":"Transaction unavailable; retry the same identity and bytes"}},"tags":["Inbound Webhooks"]}},"/inbound-webhooks/{id}/rejections":{"get":{"operationId":"list_inbound_rejections","summary":"Review retained signed-event rejections","description":"Same issuing key and matching action write scope required. Returns at most the newest 1000 unique event/body rejections retained per endpoint, including reviewed entries. No raw bodies or secrets. This is history, not an automatic replay queue.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Rejection reasons, counts, timestamps and review state"},"400":{"description":"Invalid parameters"},"401":{"description":"Missing, invalid, expired, or revoked key"},"403":{"description":"Missing explicit scope or inactive/restricted key owner"},"404":{"description":"Endpoint unavailable"},"429":{"description":"Rate limit exceeded: 120 requests per minute per key"},"500":{"description":"The request could not be completed; nothing is reported as success"}},"tags":["Inbound Webhooks"]}},"/inbound-webhooks/{id}/rejections/{rejectionId}/review":{"post":{"operationId":"review_inbound_rejection","summary":"Acknowledge a rejected attempt without replaying it","description":"Requires the same key and matching action scope. A later repeated rejection clears the reviewed state. Correct rejected data at the sender; never create a new event ID to bypass a content conflict.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"rejectionId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Review saved"},"400":{"description":"Invalid parameters"},"401":{"description":"Missing, invalid, expired, or revoked key"},"403":{"description":"Missing explicit scope or inactive/restricted key owner"},"404":{"description":"Endpoint or rejection unavailable"},"429":{"description":"Rate limit exceeded: 120 requests per minute per key"},"500":{"description":"The request could not be completed; nothing is reported as success"}},"tags":["Inbound Webhooks"]}},"/contacts/{id}/history":{"get":{"operationId":"get_customer_history","summary":"Linked customer history by record family","description":"Requires read:contacts, read:details and the selected family read scope. Includes jobs where the customer is the primary or a linked contact, plus their visits, documents and payments. Page through one record family at a time; pages are not a point-in-time snapshot.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"resource","in":"query","schema":{"type":"string","enum":["jobs","tasks","quotes","invoices","payments"],"default":"jobs"}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":4096}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Customers"]}},"/employees/{id}/route":{"get":{"operationId":"get_technician_route","summary":"Technician’s full current route","description":"Requires read:employees, read:tasks, read:details and unrestricted company access. Returns every positioned stop on the technician’s current route in driving order. Read-only: does not change the route or expose GPS. Workload totals are omitted for routes over 1,000 stops.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Employees"]}},"/jobs/{id}/equipment":{"get":{"operationId":"get_job_equipment","summary":"Recorded linked equipment and camera health","description":"Requires read:jobs and read:equipment. At most 100 cameras and 100 traps; completeness is explicit. Provider telemetry is not a new physical inspection.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Jobs"]}},"/availability":{"get":{"operationId":"check_booking_availability","summary":"Live company-widget openings","description":"Requires read:schedules. Uses the same live availability as the company’s booking widget for that service. Does not reserve or hold a slot.","parameters":[{"name":"widget_id","in":"query","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"service_id","in":"query","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"date","in":"query","required":true,"schema":{"type":"string","format":"date"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Availability"]}},"/properties":{"get":{"operationId":"list_properties","summary":"Saved customer properties","description":"Requires read:properties. Returned fields: id, contact_id, address, address_line2, latitude, longitude, is_primary_service, is_primary_billing, created_at, updated_at, company_id, app_url. Pages are ordered by ID; filters and company access bind the cursor. Company-restricted keys see only records of their companies. app_url opens the property’s own page in WildPipe.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":4096},"description":"Opaque next_cursor; repeat the same filters on every page."},{"name":"contact_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Properties"]}},"/properties/{id}":{"get":{"operationId":"get_properties","summary":"Get one: saved customer properties","description":"Requires read:properties. Returns one record with the same fields as the list.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Properties"]},"delete":{"operationId":"property_delete","summary":"Delete an unused saved property","description":"Requires write:record_deletions. Deletes a saved property that no job, visit or camera uses. When it was the primary service or billing property, the customer's oldest remaining property becomes primary. Correct an address in use with PATCH /contacts/{id}/addresses/{addressId}. Retrying with the same Idempotency-Key and identical content returns the original result without repeating the change. Recover a lost response with GET /operations/property_delete/{key}.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}},{"name":"expected_updated_at","in":"query","required":true,"schema":{"type":"string","format":"date-time","description":"The updated_at you last read. A newer value is refused with 409."}}],"responses":{"200":{"description":"Committed, or the original result of an identical retry"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Properties"]}},"/employees":{"get":{"operationId":"list_employees","summary":"Team members; no payroll or credentials","description":"Requires read:employees. Returned fields: id, first_name, last_name, role, status, is_field_technician, team_id, created_at, updated_at. Pages are ordered by ID; filters and company access bind the cursor. Organization-wide: requires an unrestricted company grant.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":4096},"description":"Opaque next_cursor; repeat the same filters on every page."},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Employees"]}},"/employees/{id}":{"get":{"operationId":"get_employees","summary":"Get one: team members; no payroll or credentials","description":"Requires read:employees. Returns one record with the same fields as the list.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Employees"]}},"/documents":{"get":{"operationId":"list_documents","summary":"Customer-linked file metadata","description":"Requires read:documents. Returned fields: id, company_id, title, description, category, file_name, mime_type, size_bytes, visibility, job_id, contact_id, quote_id, invoice_id, warranty_id, agreement_id, version, parent_document_id, expires_at, archived_at, created_at, updated_at. Pages are ordered by ID; filters and company access bind the cursor. Company-restricted keys see only records of their companies. Metadata only; employee and contractor files are excluded. Use the download endpoint for file contents.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":4096},"description":"Opaque next_cursor; repeat the same filters on every page."},{"name":"company_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"contact_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"job_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"quote_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"invoice_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Documents"]},"post":{"operationId":"document_create","summary":"Upload a document","description":"Requires write:documents. Adds a private file to one customer, job, quote or invoice. The response includes upload.url: send the file there with PUT and the same Content-Type within two hours. Repeating the request with the same Idempotency-Key returns a fresh upload link. Files are never public; customers see them in their portal only when visibility is customer. Retrying with the same Idempotency-Key and identical content returns the original result without repeating the change. Recover a lost response with GET /operations/document_create/{key}.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["title","file_name","mime_type","size_bytes"],"properties":{"title":{"type":"string","minLength":1,"maxLength":200},"description":{"type":"string","maxLength":2000,"nullable":true},"category":{"type":"string","enum":["general","agreement","invoice","quote","warranty","compliance","report","license","photo","other"],"default":"other"},"file_name":{"type":"string","minLength":1,"maxLength":255},"mime_type":{"type":"string","enum":["application/pdf","image/jpeg","image/png","image/webp","image/heic","image/heif","text/plain","text/csv","application/msword","application/vnd.openxmlformats-officedocument.wordprocessingml.document","application/vnd.ms-excel","application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"]},"size_bytes":{"type":"integer","minimum":1,"maximum":52428800},"visibility":{"type":"string","enum":["internal","customer"],"default":"internal"},"contact_id":{"type":"string","format":"uuid"},"job_id":{"type":"string","format":"uuid"},"quote_id":{"type":"string","format":"uuid"},"invoice_id":{"type":"string","format":"uuid"}}}}}},"responses":{"200":{"description":"Original result of an identical retry (replayed true)"},"201":{"description":"Committed; data holds the result and replayed is false"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Documents"]}},"/documents/{id}":{"get":{"operationId":"get_documents","summary":"Get one: customer-linked file metadata","description":"Requires read:documents. Returns one record with the same fields as the list.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Documents"]}},"/agreements":{"get":{"operationId":"list_agreements","summary":"Service agreements","description":"Requires read:agreements. Returned fields: id, company_id, job_id, contact_id, status, term_months, start_date, end_date, recurring_price, billing_frequency, service_name, agreement_title, signed_at, cancelled_at, acknowledged_at, created_at, updated_at, app_url. Pages are ordered by ID; filters and company access bind the cursor. Company-restricted keys see only records of their companies. app_url opens the agreement’s own page in WildPipe.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":4096},"description":"Opaque next_cursor; repeat the same filters on every page."},{"name":"company_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"contact_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"job_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Agreements"]}},"/agreements/{id}":{"get":{"operationId":"get_agreements","summary":"Get one: service agreements","description":"Requires read:agreements. Returns one record with the same fields as the list.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Agreements"]}},"/warranties":{"get":{"operationId":"list_warranties","summary":"Warranties","description":"Requires read:warranties. Returned fields: id, company_id, contact_id, job_id, invoice_id, warranty_type, start_date, end_date, status, next_inspection_due, requires_annual_inspection, work_signoff_id, created_at, updated_at, app_url. Pages are ordered by ID; filters and company access bind the cursor. Company-restricted keys see only records of their companies. updated_at reports the creation time for records unchanged since change tracking began, so updated_from also returns records created in the window.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":4096},"description":"Opaque next_cursor; repeat the same filters on every page."},{"name":"company_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"contact_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"job_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"invoice_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Warranties"]}},"/warranties/{id}":{"get":{"operationId":"get_warranties","summary":"Get one: warranties","description":"Requires read:warranties. Returns one record with the same fields as the list.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Warranties"]}},"/cameras":{"get":{"operationId":"list_cameras","summary":"Camera inventory and reported health","description":"Requires read:equipment. Returned fields: id, company_id, contact_id, service_address_id, meid, manufacturer, model, status, target_species, last_image_at, moultrie_battery_percentage, moultrie_last_checkin_at, created_at, updated_at, app_url. Pages are ordered by ID; filters and company access bind the cursor. Company-restricted keys see only records of their companies. updated_at reports the creation time for records unchanged since change tracking began, so updated_from also returns records created in the window.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":4096},"description":"Opaque next_cursor; repeat the same filters on every page."},{"name":"company_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"contact_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Cameras"]},"post":{"operationId":"camera_create","summary":"Add a camera to inventory","description":"Requires write:cameras. Adds a camera as unassigned and active. A camera whose MEID is already in service is refused; an archived camera with the same MEID is reactivated so its history stays together. Requires unrestricted company access. Retrying with the same Idempotency-Key and identical content returns the original result without repeating the change. Recover a lost response with GET /operations/camera_create/{key}.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["meid","serial_number","manufacturer","model"],"properties":{"meid":{"type":"string","minLength":1,"maxLength":100},"serial_number":{"type":"string","minLength":1,"maxLength":100},"manufacturer":{"type":"string","minLength":1,"maxLength":100},"model":{"type":"string","minLength":1,"maxLength":100},"platform":{"type":"string","maxLength":100,"nullable":true},"battery_pack_type":{"type":"string","enum":["aa_batteries","lithium_pack"]}}}}}},"responses":{"200":{"description":"Original result of an identical retry (replayed true)"},"201":{"description":"Committed; data holds the result and replayed is false"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Cameras"]}},"/cameras/{id}":{"get":{"operationId":"get_cameras","summary":"Get one: camera inventory and reported health","description":"Requires read:equipment. Returns one record with the same fields as the list.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Cameras"]},"patch":{"operationId":"camera_update","summary":"Change camera details","description":"Requires write:cameras. Updates hardware details, target species, site notes and dog warnings. Customer and address details follow the assigned job. Retrying with the same Idempotency-Key and identical content returns the original result without repeating the change. Recover a lost response with GET /operations/camera_update/{key}.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["expected_updated_at"],"properties":{"expected_updated_at":{"type":"string","format":"date-time","description":"The updated_at you last read. A newer value is refused with 409."},"manufacturer":{"type":"string","minLength":1,"maxLength":100},"model":{"type":"string","minLength":1,"maxLength":100},"platform":{"type":"string","maxLength":100,"nullable":true},"battery_pack_type":{"type":"string","enum":["aa_batteries","lithium_pack"]},"target_species":{"type":"array","maxItems":20,"items":{"type":"string","minLength":1,"maxLength":60}},"destination_notes":{"type":"string","maxLength":5000,"nullable":true},"has_dog":{"type":"boolean"},"is_dog_dangerous":{"type":"boolean"},"dog_in_area":{"type":"boolean"}}}}}},"responses":{"200":{"description":"Committed, or the original result of an identical retry"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Cameras"]}},"/treatments":{"get":{"operationId":"list_treatments","summary":"Treatment application records with products used, applicator and conditions","description":"Requires read:treatments. Returned fields: id, job_id, task_id, rule_state_code, application_started_at, application_ended_at, application_address, site_type, application_method, target_pests, treated_area, treated_area_unit, products, applicator_name, applicator_license_number, applicator_license_state, weather_temperature_f, weather_wind_mph, weather_wind_direction, weather_conditions, restricted_entry_hours, reentry_at, customer_notified, notification_method, label_followed_attestation, attested_at, created_at, updated_at, company_id. Pages are ordered by ID; filters and company access bind the cursor. Company-restricted keys see only records of their companies. updated_at reports the creation time for records unchanged since change tracking began, so updated_from also returns records created in the window.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":4096},"description":"Opaque next_cursor; repeat the same filters on every page."},{"name":"job_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"task_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Treatments"]}},"/treatments/{id}":{"get":{"operationId":"get_treatments","summary":"Get one: treatment application records with products used, applicator and conditions","description":"Requires read:treatments. Returns one record with the same fields as the list.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Treatments"]}},"/treatment_products":{"get":{"operationId":"list_treatment_products","summary":"Treatment products and chemicals; internal costs excluded","description":"Requires read:treatments. Returned fields: id, name, manufacturer, epa_registration_number, active_ingredients, category, unit_of_measure, signal_word, restricted_use, sds_url, label_image_url, barcode, is_active, created_at, updated_at. Pages are ordered by ID; filters and company access bind the cursor. Organization-wide: requires an unrestricted company grant. updated_at reports the creation time for records unchanged since change tracking began, so updated_from also returns records created in the window.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":4096},"description":"Opaque next_cursor; repeat the same filters on every page."},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Treatment Products"]}},"/treatment_products/{id}":{"get":{"operationId":"get_treatment_products","summary":"Get one: treatment products and chemicals; internal costs excluded","description":"Requires read:treatments. Returns one record with the same fields as the list.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Treatment Products"]}},"/credits":{"get":{"operationId":"list_credits","summary":"Customer credits","description":"Requires read:credits. Returned fields: id, contact_id, invoice_id, credit_number, amount, remaining_balance, reason, status, created_at, updated_at, company_id. Pages are ordered by ID; filters and company access bind the cursor. Company-restricted keys see only records of their companies. updated_at reports the creation time for records unchanged since change tracking began, so updated_from also returns records created in the window.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":4096},"description":"Opaque next_cursor; repeat the same filters on every page."},{"name":"contact_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"invoice_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Credits"]},"post":{"operationId":"credit_create","summary":"Issue a customer credit","description":"Requires write:credits. Issues a credit memo to a customer, as the office Issue Credit action does. Optionally link the invoice it relates to. Retrying with the same Idempotency-Key and identical content returns the original result without repeating the change. Recover a lost response with GET /operations/credit_create/{key}.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["contact_id","amount"],"properties":{"contact_id":{"type":"string","format":"uuid"},"amount":{"type":"number","exclusiveMinimum":0,"maximum":50000,"multipleOf":0.01},"reason":{"type":"string","maxLength":200,"nullable":true},"notes":{"type":"string","maxLength":2000,"nullable":true},"invoice_id":{"type":"string","format":"uuid"}}}}}},"responses":{"200":{"description":"Original result of an identical retry (replayed true)"},"201":{"description":"Committed; data holds the result and replayed is false"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Credits"]}},"/credits/{id}":{"get":{"operationId":"get_credits","summary":"Get one: customer credits","description":"Requires read:credits. Returns one record with the same fields as the list.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Credits"]}},"/tags":{"get":{"operationId":"list_tags","summary":"Tag definitions and safety flags","description":"Requires read:tags. Returned fields: id, name, color, entity_scope, is_danger, is_system, created_at, updated_at. Pages are ordered by ID; filters and company access bind the cursor. Organization-wide: requires an unrestricted company grant. updated_at reports the creation time for records unchanged since change tracking began, so updated_from also returns records created in the window.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":4096},"description":"Opaque next_cursor; repeat the same filters on every page."},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Tags"]},"post":{"operationId":"tag_create","summary":"Create a tag","description":"Requires write:tags. Adds a tag to your organization's tag list. Names are unique regardless of case. Requires unrestricted company access. Retrying with the same Idempotency-Key and identical content returns the original result without repeating the change. Recover a lost response with GET /operations/tag_create/{key}.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["name"],"properties":{"name":{"type":"string","minLength":1,"maxLength":60},"color":{"type":"string","pattern":"^(#[0-9A-Fa-f]{6}|[a-z]{3,20})$"},"entity_scope":{"type":"string","enum":["contact","job","both"],"description":"Where the tag can be used"},"is_danger":{"type":"boolean","description":"Shows a safety warning wherever the customer appears. Customer tags only."}}}}}},"responses":{"200":{"description":"Original result of an identical retry (replayed true)"},"201":{"description":"Committed; data holds the result and replayed is false"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Tags"]}},"/tags/{id}":{"get":{"operationId":"get_tags","summary":"Get one: tag definitions and safety flags","description":"Requires read:tags. Returns one record with the same fields as the list.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Tags"]},"patch":{"operationId":"tag_update","summary":"Change a tag","description":"Requires write:tags. Renames or recolors a tag, changes where it can be used, or turns its safety warning on or off. A scope change is refused while customers or jobs still use the tag where it would no longer apply. Built-in tags cannot be renamed. Requires unrestricted company access. Retrying with the same Idempotency-Key and identical content returns the original result without repeating the change. Recover a lost response with GET /operations/tag_update/{key}.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["expected_updated_at"],"properties":{"expected_updated_at":{"type":"string","format":"date-time","description":"The updated_at you last read. A newer value is refused with 409."},"name":{"type":"string","minLength":1,"maxLength":60},"color":{"type":"string","pattern":"^(#[0-9A-Fa-f]{6}|[a-z]{3,20})$"},"entity_scope":{"type":"string","enum":["contact","job","both"],"description":"Where the tag can be used"},"is_danger":{"type":"boolean","description":"Shows a safety warning wherever the customer appears. Customer tags only."}}}}}},"responses":{"200":{"description":"Committed, or the original result of an identical retry"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Tags"]},"delete":{"operationId":"tag_delete","summary":"Delete a tag","description":"Requires write:tags. Deletes a tag and removes it from every customer and job, as the office does. Built-in tags cannot be deleted. Requires unrestricted company access. Retrying with the same Idempotency-Key and identical content returns the original result without repeating the change. Recover a lost response with GET /operations/tag_delete/{key}.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}},{"name":"expected_updated_at","in":"query","required":true,"schema":{"type":"string","format":"date-time","description":"The updated_at you last read. A newer value is refused with 409."}}],"responses":{"200":{"description":"Committed, or the original result of an identical retry"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Tags"]}},"/schedules":{"get":{"operationId":"list_schedules","summary":"Technician weekly hours (Team Schedule shifts; a day can have several, and later effective dates replace earlier ones)","description":"Requires read:schedules. Returned fields: id, user_id, day_of_week, start_time, end_time, is_available, work_type, effective_from, sort_order, created_at, updated_at. Pages are ordered by ID; filters and company access bind the cursor. Organization-wide: requires an unrestricted company grant. Weekly hours are not live booking availability.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":4096},"description":"Opaque next_cursor; repeat the same filters on every page."},{"name":"user_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Schedules"]}},"/schedules/{id}":{"get":{"operationId":"get_schedules","summary":"Get one: technician weekly hours (team schedule shifts; a day can have several, and later effective dates replace earlier ones)","description":"Requires read:schedules. Returns one record with the same fields as the list.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Schedules"]}},"/subscriptions":{"get":{"operationId":"list_subscriptions","summary":"Recurring plans","description":"Requires read:details and read:jobs. Returned fields: id, company_id, contact_id, booking_number, subscription_status, recurrence_interval, billing_frequency, next_service_date, billing_paused, subscription_skip_next_visit, commitment_end_date, auto_pay_enabled, created_at, updated_at. Pages are ordered by ID; filters and company access bind the cursor. Company-restricted keys see only records of their companies.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":4096},"description":"Opaque next_cursor; repeat the same filters on every page."},{"name":"company_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"contact_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Subscriptions"]}},"/subscriptions/{id}":{"get":{"operationId":"get_subscriptions","summary":"Get one: recurring plans","description":"Requires read:details and read:jobs. Returns one record with the same fields as the list.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Subscriptions"]}},"/collections":{"get":{"operationId":"list_collections","summary":"Collection cases","description":"Requires read:details and read:invoices. Returned fields: id, company_id, contact_id, invoice_id, case_number, origin, status, amount_owed, amount_recovered, amount_written_off, opened_at, closed_at, created_at, updated_at. Pages are ordered by ID; filters and company access bind the cursor. Company-restricted keys see only records of their companies.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":4096},"description":"Opaque next_cursor; repeat the same filters on every page."},{"name":"company_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"contact_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"invoice_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Collections"]}},"/collections/{id}":{"get":{"operationId":"get_collections","summary":"Get one: collection cases","description":"Requires read:details and read:invoices. Returns one record with the same fields as the list.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Collections"]}},"/disputes":{"get":{"operationId":"list_disputes","summary":"Payment disputes","description":"Requires read:details and read:payments. Returned fields: id, company_id, payment_id, invoice_id, job_id, provider, state, amount, currency, link_status, reversed_at, loss_recorded_at, disputed_at, created_at, updated_at. Pages are ordered by ID; filters and company access bind the cursor. Company-restricted keys see only records of their companies.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":4096},"description":"Opaque next_cursor; repeat the same filters on every page."},{"name":"company_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"invoice_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"job_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Disputes"]}},"/disputes/{id}":{"get":{"operationId":"get_disputes","summary":"Get one: payment disputes","description":"Requires read:details and read:payments. Returns one record with the same fields as the list.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Disputes"]}},"/task_types":{"get":{"operationId":"list_task_types","summary":"Active task types","description":"Requires read:details and read:tasks. Returned fields: id, name, slug, is_active, stop_reasons, require_notes, require_photos, require_signature, require_approval, requires_work_signoff, created_at, updated_at. Pages are ordered by ID; filters and company access bind the cursor. Organization-wide: requires an unrestricted company grant.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":4096},"description":"Opaque next_cursor; repeat the same filters on every page."},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Task Types"]}},"/task_types/{id}":{"get":{"operationId":"get_task_types","summary":"Get one: active task types","description":"Requires read:details and read:tasks. Returns one record with the same fields as the list.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Task Types"]}},"/calls":{"get":{"operationId":"list_calls","summary":"Phone calls (no recordings or transcripts)","description":"Requires read:communications. Returned fields: id, company_id, contact_id, job_id, user_id, call_reference, direction, status, from_number, to_number, duration, disposition, ai_agent_id, recording_duration, created_at, updated_at. Pages are ordered by ID; filters and company access bind the cursor. Company-restricted keys see only records of their companies. Internal staff calls, transfers and duplicate provider legs are excluded. Recordings are not exposed; transcripts and AI summaries need read:transcripts.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":4096},"description":"Opaque next_cursor; repeat the same filters on every page."},{"name":"company_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"contact_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"job_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Communications"]}},"/calls/{id}":{"get":{"operationId":"get_calls","summary":"Get one: phone calls (no recordings or transcripts)","description":"Requires read:communications. Returns one record with the same fields as the list.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Communications"]}},"/call_transcripts":{"get":{"operationId":"list_call_transcripts","summary":"Call transcripts; id matches the call","description":"Requires read:transcripts and read:communications. Returned fields: id, company_id, contact_id, job_id, call_reference, transcript, created_at, updated_at. Pages are ordered by ID; filters and company access bind the cursor. Company-restricted keys see only records of their companies. Only customer calls that have a transcript. The id is the call id.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":4096},"description":"Opaque next_cursor; repeat the same filters on every page."},{"name":"company_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"contact_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"job_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Communications"]}},"/call_transcripts/{id}":{"get":{"operationId":"get_call_transcripts","summary":"Get one: call transcripts; id matches the call","description":"Requires read:transcripts and read:communications. Returns one record with the same fields as the list.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Communications"]}},"/call_summaries":{"get":{"operationId":"list_call_summaries","summary":"AI call summaries; match calls by call_reference","description":"Requires read:transcripts and read:communications. Returned fields: id, call_reference, summary, detailed_notes, service_discussed, price_quoted, customer_objection, urgency, has_lead, has_appointment, has_follow_up, is_new_customer, created_at, updated_at. Pages are ordered by ID; filters and company access bind the cursor. Organization-wide: requires an unrestricted company grant. Match a summary to its call with call_reference.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":4096},"description":"Opaque next_cursor; repeat the same filters on every page."},{"name":"call_reference","in":"query","schema":{"type":"string","maxLength":120},"description":"Exact match."},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Communications"]}},"/call_summaries/{id}":{"get":{"operationId":"get_call_summaries","summary":"Get one: ai call summaries; match calls by call_reference","description":"Requires read:transcripts and read:communications. Returns one record with the same fields as the list.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Communications"]}},"/text_messages":{"get":{"operationId":"list_text_messages","summary":"Text messages","description":"Requires read:communications. Returned fields: id, company_id, contact_id, job_id, user_id, direction, status, from_number, to_number, body, num_media, delivered_at, error_code, created_at, updated_at. Pages are ordered by ID; filters and company access bind the cursor. Company-restricted keys see only records of their companies.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":4096},"description":"Opaque next_cursor; repeat the same filters on every page."},{"name":"company_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"contact_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"job_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Communications"]}},"/text_messages/{id}":{"get":{"operationId":"get_text_messages","summary":"Get one: text messages","description":"Requires read:communications. Returns one record with the same fields as the list.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Communications"]}},"/outbound_emails":{"get":{"operationId":"list_outbound_emails","summary":"Company emails sent to customers; personal mailboxes excluded","description":"Requires read:communications. Returned fields: id, company_id, contact_id, job_id, invoice_id, quote_id, to_email, from_email, from_name, subject, body_text, body_html, status, delivered_at, opened_at, bounced_at, thread_id, created_at, updated_at. Pages are ordered by ID; filters and company access bind the cursor. Company-restricted keys see only records of their companies. Company email only; staff members’ personal mailboxes are never included. Delivery and open times come from the email provider and are not proof of reading.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":4096},"description":"Opaque next_cursor; repeat the same filters on every page."},{"name":"company_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"contact_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"job_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Communications"]}},"/outbound_emails/{id}":{"get":{"operationId":"get_outbound_emails","summary":"Get one: company emails sent to customers; personal mailboxes excluded","description":"Requires read:communications. Returns one record with the same fields as the list.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Communications"]}},"/inbound_emails":{"get":{"operationId":"list_inbound_emails","summary":"Emails received at company addresses; spam and personal mailboxes excluded","description":"Requires read:communications. Returned fields: id, company_id, contact_id, job_id, from_email, from_name, to_email, subject, body_text, body_html, is_read, thread_id, created_at, updated_at. Pages are ordered by ID; filters and company access bind the cursor. Company-restricted keys see only records of their companies. Mail received at company addresses only; spam and staff members’ personal mailboxes are never included.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":4096},"description":"Opaque next_cursor; repeat the same filters on every page."},{"name":"company_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"contact_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"job_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Communications"]}},"/inbound_emails/{id}":{"get":{"operationId":"get_inbound_emails","summary":"Get one: emails received at company addresses; spam and personal mailboxes excluded","description":"Requires read:communications. Returns one record with the same fields as the list.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Communications"]}},"/chats":{"get":{"operationId":"list_chats","summary":"Website chat conversations","description":"Requires read:communications. Returned fields: id, company_id, contact_id, widget_id, status, rating, rating_feedback, created_at, updated_at. Pages are ordered by ID; filters and company access bind the cursor. Company-restricted keys see only records of their companies.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":4096},"description":"Opaque next_cursor; repeat the same filters on every page."},{"name":"company_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"contact_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Communications"]}},"/chats/{id}":{"get":{"operationId":"get_chats","summary":"Get one: website chat conversations","description":"Requires read:communications. Returns one record with the same fields as the list.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Communications"]}},"/chat_messages":{"get":{"operationId":"list_chat_messages","summary":"Website chat messages","description":"Requires read:communications. Returned fields: id, chat_id, sender_type, content, file_name, file_type, created_at, updated_at, company_id. Pages are ordered by ID; filters and company access bind the cursor. Company-restricted keys see only records of their companies. updated_at reports the creation time for records unchanged since change tracking began, so updated_from also returns records created in the window. Attachments are reported by name and type only.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":4096},"description":"Opaque next_cursor; repeat the same filters on every page."},{"name":"chat_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Communications"]}},"/chat_messages/{id}":{"get":{"operationId":"get_chat_messages","summary":"Get one: website chat messages","description":"Requires read:communications. Returns one record with the same fields as the list.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Communications"]}},"/timeline":{"get":{"operationId":"list_timeline","summary":"Full notes and activity timeline","description":"Requires read:communications. Returned fields: id, type, source, content, visibility, status, user_id, contact_id, job_id, task_id, quote_id, invoice_id, lead_id, payment_id, created_at, updated_at. Pages are ordered by ID; filters and company access bind the cursor. Organization-wide: requires an unrestricted company grant. updated_at reports the creation time for records unchanged since change tracking began, so updated_from also returns records created in the window. Every note and activity entry, including call, form, quote and AI events. Filter type for one kind of entry.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":4096},"description":"Opaque next_cursor; repeat the same filters on every page."},{"name":"contact_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"job_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"task_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"type","in":"query","schema":{"type":"string","maxLength":120},"description":"Exact match."},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Communications"]}},"/timeline/{id}":{"get":{"operationId":"get_timeline","summary":"Get one: full notes and activity timeline","description":"Requires read:communications. Returns one record with the same fields as the list.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Communications"]}},"/timeline_replies":{"get":{"operationId":"list_timeline_replies","summary":"Replies on timeline entries","description":"Requires read:communications. Returned fields: id, timeline_id, user_id, content, visibility, created_at, updated_at. Pages are ordered by ID; filters and company access bind the cursor. Organization-wide: requires an unrestricted company grant. updated_at reports the creation time for records unchanged since change tracking began, so updated_from also returns records created in the window.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":4096},"description":"Opaque next_cursor; repeat the same filters on every page."},{"name":"timeline_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Communications"]}},"/timeline_replies/{id}":{"get":{"operationId":"get_timeline_replies","summary":"Get one: replies on timeline entries","description":"Requires read:communications. Returns one record with the same fields as the list.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Communications"]}},"/visit_form_answers":{"get":{"operationId":"list_visit_form_answers","summary":"Visit form answers","description":"Requires read:field_records and read:tasks. Returned fields: id, task_id, phase, field_key, field_name, value_text, value_number, value_boolean, value_json, created_at, updated_at, company_id. Pages are ordered by ID; filters and company access bind the cursor. Company-restricted keys see only records of their companies.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":4096},"description":"Opaque next_cursor; repeat the same filters on every page."},{"name":"task_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Field & Compliance"]}},"/visit_form_answers/{id}":{"get":{"operationId":"get_visit_form_answers","summary":"Get one: visit form answers","description":"Requires read:field_records and read:tasks. Returns one record with the same fields as the list.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Field & Compliance"]}},"/visit_assignments":{"get":{"operationId":"list_visit_assignments","summary":"Primary and crew visit assignments","description":"Requires read:field_records and read:tasks. Returned fields: id, task_id, user_id, role, status, status_changed_at, completed_at, completed_notes, removed_at, created_at, updated_at, company_id. Pages are ordered by ID; filters and company access bind the cursor. Company-restricted keys see only records of their companies. updated_at reports the creation time for records unchanged since change tracking began, so updated_from also returns records created in the window. Removed assignments remain, with removed_at set. Signatures and photos are excluded.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":4096},"description":"Opaque next_cursor; repeat the same filters on every page."},{"name":"task_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"user_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Field & Compliance"]}},"/visit_assignments/{id}":{"get":{"operationId":"get_visit_assignments","summary":"Get one: primary and crew visit assignments","description":"Requires read:field_records and read:tasks. Returns one record with the same fields as the list.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Field & Compliance"]}},"/inspection_reports":{"get":{"operationId":"list_inspection_reports","summary":"Inspection reports with their question set","description":"Requires read:field_records. Returned fields: id, company_id, job_id, task_id, template_id, module, status, template_snapshot, created_by, completed_at, created_at, updated_at, app_url. Pages are ordered by ID; filters and company access bind the cursor. Company-restricted keys see only records of their companies. updated_at reports the creation time for records unchanged since change tracking began, so updated_from also returns records created in the window. template_snapshot holds the question set the answers refer to.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":4096},"description":"Opaque next_cursor; repeat the same filters on every page."},{"name":"company_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"job_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"task_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Field & Compliance"]}},"/inspection_reports/{id}":{"get":{"operationId":"get_inspection_reports","summary":"Get one: inspection reports with their question set","description":"Requires read:field_records. Returns one record with the same fields as the list.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Field & Compliance"]}},"/inspection_report_answers":{"get":{"operationId":"list_inspection_report_answers","summary":"Inspection report answers","description":"Requires read:field_records. Returned fields: id, report_id, question_id, answer_text, answer_data, created_at, updated_at, company_id. Pages are ordered by ID; filters and company access bind the cursor. Company-restricted keys see only records of their companies. updated_at reports the creation time for records unchanged since change tracking began, so updated_from also returns records created in the window.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":4096},"description":"Opaque next_cursor; repeat the same filters on every page."},{"name":"report_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Field & Compliance"]}},"/inspection_report_answers/{id}":{"get":{"operationId":"get_inspection_report_answers","summary":"Get one: inspection report answers","description":"Requires read:field_records. Returns one record with the same fields as the list.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Field & Compliance"]}},"/work_signoffs":{"get":{"operationId":"list_work_signoffs","summary":"Final work signoffs (no signature images)","description":"Requires read:field_records. Returned fields: id, company_id, job_id, quote_id, invoice_id, final_task_id, version, status, technician_id, technician_certified_at, technician_notes, customer_name, customer_signed_at, scope_snapshot, warranty_id, voided_at, void_reason, created_at, updated_at. Pages are ordered by ID; filters and company access bind the cursor. Company-restricted keys see only records of their companies. Customer signature images, IP addresses and device details are excluded.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":4096},"description":"Opaque next_cursor; repeat the same filters on every page."},{"name":"company_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"job_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"quote_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Field & Compliance"]}},"/work_signoffs/{id}":{"get":{"operationId":"get_work_signoffs","summary":"Get one: final work signoffs (no signature images)","description":"Requires read:field_records. Returns one record with the same fields as the list.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Field & Compliance"]}},"/warranty_items":{"get":{"operationId":"list_warranty_items","summary":"Covered warranty items","description":"Requires read:field_records and read:warranties. Returned fields: id, warranty_id, description, quantity, coverage_terms, created_at, updated_at, company_id. Pages are ordered by ID; filters and company access bind the cursor. Company-restricted keys see only records of their companies. updated_at reports the creation time for records unchanged since change tracking began, so updated_from also returns records created in the window.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":4096},"description":"Opaque next_cursor; repeat the same filters on every page."},{"name":"warranty_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Field & Compliance"]}},"/warranty_items/{id}":{"get":{"operationId":"get_warranty_items","summary":"Get one: covered warranty items","description":"Requires read:field_records and read:warranties. Returns one record with the same fields as the list.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Field & Compliance"]}},"/bait_stations":{"get":{"operationId":"list_bait_stations","summary":"Bait stations","description":"Requires read:field_records. Returned fields: id, job_id, contact_id, barcode, station_type, location_description, lat, lng, address, status, activity_level, check_frequency_hours, last_checked_at, next_check_due, installed_at, notes, created_at, updated_at, company_id, app_url. Pages are ordered by ID; filters and company access bind the cursor. Company-restricted keys see only records of their companies.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":4096},"description":"Opaque next_cursor; repeat the same filters on every page."},{"name":"job_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"contact_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Field & Compliance"]},"post":{"operationId":"station_create","summary":"Install a bait station on a job","description":"Requires write:bait_stations. Adds an active bait station to a job at the job property. Retrying with the same Idempotency-Key and identical content returns the original result without repeating the change. Recover a lost response with GET /operations/station_create/{key}.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["job_id"],"properties":{"job_id":{"type":"string","format":"uuid"},"barcode":{"type":"string","maxLength":100,"nullable":true},"station_type":{"type":"string","maxLength":100,"nullable":true},"location_description":{"type":"string","maxLength":1000,"nullable":true},"lat":{"type":"number","minimum":-90,"maximum":90,"nullable":true},"lng":{"type":"number","minimum":-180,"maximum":180,"nullable":true},"check_frequency_hours":{"type":"integer","minimum":1,"maximum":8760,"nullable":true},"notes":{"type":"string","maxLength":5000,"nullable":true}}}}}},"responses":{"200":{"description":"Original result of an identical retry (replayed true)"},"201":{"description":"Committed; data holds the result and replayed is false"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Field & Compliance"]}},"/bait_stations/{id}":{"get":{"operationId":"get_bait_stations","summary":"Get one: bait stations","description":"Requires read:field_records. Returns one record with the same fields as the list.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Field & Compliance"]},"patch":{"operationId":"station_update","summary":"Change a bait station","description":"Requires write:bait_stations. Updates station details or status. Checks are recorded by field work. Retrying with the same Idempotency-Key and identical content returns the original result without repeating the change. Recover a lost response with GET /operations/station_update/{key}.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["expected_updated_at"],"properties":{"expected_updated_at":{"type":"string","format":"date-time","description":"The updated_at you last read. A newer value is refused with 409."},"barcode":{"type":"string","maxLength":100,"nullable":true},"station_type":{"type":"string","maxLength":100,"nullable":true},"location_description":{"type":"string","maxLength":1000,"nullable":true},"lat":{"type":"number","minimum":-90,"maximum":90,"nullable":true},"lng":{"type":"number","minimum":-180,"maximum":180,"nullable":true},"check_frequency_hours":{"type":"integer","minimum":1,"maximum":8760,"nullable":true},"notes":{"type":"string","maxLength":5000,"nullable":true},"status":{"type":"string","enum":["active","inactive","needs_service","damaged","removed"]}}}}}},"responses":{"200":{"description":"Committed, or the original result of an identical retry"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Field & Compliance"]}},"/station_checks":{"get":{"operationId":"list_station_checks","summary":"Bait station checks","description":"Requires read:field_records. Returned fields: id, station_id, task_id, checked_by, checked_at, activity_level, bait_condition, station_condition, action_taken, product_amount, product_unit, notes, created_at, updated_at. Pages are ordered by ID; filters and company access bind the cursor. Organization-wide: requires an unrestricted company grant. updated_at reports the creation time for records unchanged since change tracking began, so updated_from also returns records created in the window.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":4096},"description":"Opaque next_cursor; repeat the same filters on every page."},{"name":"station_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"task_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Field & Compliance"]}},"/station_checks/{id}":{"get":{"operationId":"get_station_checks","summary":"Get one: bait station checks","description":"Requires read:field_records. Returns one record with the same fields as the list.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Field & Compliance"]}},"/traps":{"get":{"operationId":"list_traps","summary":"Trap inventory and placement","description":"Requires read:field_records. Returned fields: id, label, serial_number, trap_type, target_species, status, address, latitude, longitude, check_frequency_hours, last_checked_at, next_check_due, has_dog, is_dog_dangerous, dog_in_area, notes, created_at, updated_at, app_url. Pages are ordered by ID; filters and company access bind the cursor. Organization-wide: requires an unrestricted company grant.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":4096},"description":"Opaque next_cursor; repeat the same filters on every page."},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Field & Compliance"]},"post":{"operationId":"trap_create","summary":"Add a trap to inventory","description":"Requires write:equipment. Adds a trap as available (or needs_service/retired). Requires unrestricted company access. Retrying with the same Idempotency-Key and identical content returns the original result without repeating the change. Recover a lost response with GET /operations/trap_create/{key}.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["label","trap_type"],"properties":{"label":{"type":"string","minLength":1,"maxLength":100},"trap_type":{"type":"string","minLength":1,"maxLength":100},"serial_number":{"type":"string","maxLength":100,"nullable":true},"notes":{"type":"string","maxLength":5000,"nullable":true},"target_species":{"type":"array","maxItems":20,"items":{"type":"string","minLength":1,"maxLength":60}},"check_frequency_hours":{"type":"integer","minimum":1,"maximum":720,"nullable":true},"status":{"type":"string","enum":["available","needs_service","retired"],"description":"Deployed and on-truck states are set only by field work."}}}}}},"responses":{"200":{"description":"Original result of an identical retry (replayed true)"},"201":{"description":"Committed; data holds the result and replayed is false"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Field & Compliance"]}},"/traps/{id}":{"get":{"operationId":"get_traps","summary":"Get one: trap inventory and placement","description":"Requires read:field_records. Returns one record with the same fields as the list.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Field & Compliance"]},"patch":{"operationId":"trap_update","summary":"Change a trap","description":"Requires write:equipment. Updates trap details. status may only move between available, needs_service and retired while the trap is not deployed or on a truck. Requires unrestricted company access. Retrying with the same Idempotency-Key and identical content returns the original result without repeating the change. Recover a lost response with GET /operations/trap_update/{key}.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["expected_updated_at"],"properties":{"expected_updated_at":{"type":"string","format":"date-time","description":"The updated_at you last read. A newer value is refused with 409."},"label":{"type":"string","minLength":1,"maxLength":100},"trap_type":{"type":"string","minLength":1,"maxLength":100},"serial_number":{"type":"string","maxLength":100,"nullable":true},"notes":{"type":"string","maxLength":5000,"nullable":true},"target_species":{"type":"array","maxItems":20,"items":{"type":"string","minLength":1,"maxLength":60}},"check_frequency_hours":{"type":"integer","minimum":1,"maximum":720,"nullable":true},"status":{"type":"string","enum":["available","needs_service","retired"],"description":"Deployed and on-truck states are set only by field work."}}}}}},"responses":{"200":{"description":"Committed, or the original result of an identical retry"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Field & Compliance"]},"delete":{"operationId":"trap_delete","summary":"Delete an unused trap","description":"Requires write:equipment. Deletes a trap that has never been on a job, truck or check. Traps with history must be retired instead so their records stay intact. Requires unrestricted company access. Retrying with the same Idempotency-Key and identical content returns the original result without repeating the change. Recover a lost response with GET /operations/trap_delete/{key}.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}},{"name":"expected_updated_at","in":"query","required":true,"schema":{"type":"string","format":"date-time","description":"The updated_at you last read. A newer value is refused with 409."}}],"responses":{"200":{"description":"Committed, or the original result of an identical retry"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Field & Compliance"]}},"/commissions":{"get":{"operationId":"list_commissions","summary":"Commission ledger","description":"Requires read:payroll. Returned fields: id, company_id, user_id, job_id, task_id, invoice_id, quote_id, commission_type, commission_phase, assignment_role, service_name, service_total, commission_rate, commission_amount, status, source, hold_until_work_completed, approved_at, denied_at, denial_reason, paid_at, created_at, updated_at. Pages are ordered by ID; filters and company access bind the cursor. Company-restricted keys see only records of their companies. Includes pending, approved, held, denied and paid entries; only paid entries were paid out.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":4096},"description":"Opaque next_cursor; repeat the same filters on every page."},{"name":"company_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"user_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"job_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Payroll"]}},"/commissions/{id}":{"get":{"operationId":"get_commissions","summary":"Get one: commission ledger","description":"Requires read:payroll. Returns one record with the same fields as the list.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Payroll"]}},"/time_entries":{"get":{"operationId":"list_time_entries","summary":"Clock-in and clock-out records","description":"Requires read:payroll. Returned fields: id, company_id, user_id, clock_in, clock_out, paid_at, created_at, updated_at. Pages are ordered by ID; filters and company access bind the cursor. Company-restricted keys see only records of their companies. updated_at reports the creation time for records unchanged since change tracking began, so updated_from also returns records created in the window.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":4096},"description":"Opaque next_cursor; repeat the same filters on every page."},{"name":"company_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"user_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Payroll"]}},"/time_entries/{id}":{"get":{"operationId":"get_time_entries","summary":"Get one: clock-in and clock-out records","description":"Requires read:payroll. Returns one record with the same fields as the list.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Payroll"]}},"/complaints":{"get":{"operationId":"list_complaints","summary":"Customer concerns","description":"Requires read:complaints. Returned fields: id, company_id, contact_id, job_id, summary, source, status, version, created_at, updated_at, app_url. Pages are ordered by ID; filters and company access bind the cursor. Company-restricted keys see only records of their companies.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":4096},"description":"Opaque next_cursor; repeat the same filters on every page."},{"name":"company_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"contact_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"job_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Customer Concerns"]},"post":{"operationId":"complaint_create","summary":"Record a customer concern","description":"Requires write:complaints. Records a concern for a customer, optionally linked to one of their jobs or visits, exactly as the office does: it gets its own office follow-up task and marks the linked visit as complained about. When only job_id is sent and the job has exactly one open visit, that visit is linked. Never contacts the customer. Retrying with the same Idempotency-Key and identical content returns the original result without repeating the change. Recover a lost response with GET /operations/complaint_create/{key}.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["contact_id","summary"],"properties":{"contact_id":{"type":"string","format":"uuid"},"summary":{"type":"string","minLength":3,"maxLength":5000},"job_id":{"type":"string","format":"uuid"},"task_id":{"type":"string","format":"uuid"}}}}}},"responses":{"200":{"description":"Original result of an identical retry (replayed true)"},"201":{"description":"Committed; data holds the result and replayed is false"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Customer Concerns"]}},"/complaints/{id}":{"get":{"operationId":"get_complaints","summary":"Get one: customer concerns","description":"Requires read:complaints. Returns one record with the same fields as the list.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Customer Concerns"]},"patch":{"operationId":"complaint_update","summary":"Update a customer concern","description":"Requires write:complaints. Adds a note and optionally changes status (open, addressing, resolved), links an unlinked concern to one of the customer's jobs, or links a recovery visit on that job. Resolving closes the concern's office follow-up task; completing a visit never resolves a concern. Retrying with the same Idempotency-Key and identical content returns the original result without repeating the change. Recover a lost response with GET /operations/complaint_update/{key}.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["expected_updated_at","note"],"properties":{"expected_updated_at":{"type":"string","format":"date-time","description":"The updated_at you last read. A newer value is refused with 409."},"note":{"type":"string","minLength":3,"maxLength":5000},"status":{"type":"string","enum":["open","addressing","resolved"]},"job_id":{"type":"string","format":"uuid"},"recovery_task_id":{"type":"string","format":"uuid"}}}}}},"responses":{"200":{"description":"Committed, or the original result of an identical retry"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Customer Concerns"]}},"/online_bookings":{"get":{"operationId":"list_online_bookings","summary":"Online booking requests","description":"Requires read:bookings. Returned fields: id, contact_id, job_id, widget_id, booking_number, service_name, customer_notes, status, requested_time, created_at, updated_at, company_id. Pages are ordered by ID; filters and company access bind the cursor. Company-restricted keys see only records of their companies. updated_at reports the creation time for records unchanged since change tracking began, so updated_from also returns records created in the window.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":4096},"description":"Opaque next_cursor; repeat the same filters on every page."},{"name":"contact_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"job_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Online Bookings"]}},"/online_bookings/{id}":{"get":{"operationId":"get_online_bookings","summary":"Get one: online booking requests","description":"Requires read:bookings. Returns one record with the same fields as the list.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Online Bookings"]}},"/variants":{"get":{"operationId":"list_variants","summary":"All service and product variants; internal costs excluded","description":"Requires read:services and read:products. Returned fields: id, service_id, product_id, name, description, price, initial_price, recurring_price, sku, warranty_terms, created_at, updated_at. Pages are ordered by ID; filters and company access bind the cursor. Organization-wide: requires an unrestricted company grant. Internal unit costs are excluded.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":4096},"description":"Opaque next_cursor; repeat the same filters on every page."},{"name":"service_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"product_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Services"]}},"/variants/{id}":{"get":{"operationId":"get_variants","summary":"Get one: all service and product variants; internal costs excluded","description":"Requires read:services and read:products. Returns one record with the same fields as the list.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Services"]}},"/expenses":{"get":{"operationId":"list_expenses","summary":"Employee expenses","description":"Requires read:payroll. Returned fields: id, user_id, category, amount, vendor, description, expense_date, status, approved_by, approved_at, job_id, vehicle_id, is_billable, payment_method, created_at, updated_at. Pages are ordered by ID; filters and company access bind the cursor. Organization-wide: requires an unrestricted company grant. updated_at reports the creation time for records unchanged since change tracking began, so updated_from also returns records created in the window.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":4096},"description":"Opaque next_cursor; repeat the same filters on every page."},{"name":"user_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"job_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Expenses"]},"post":{"operationId":"expense_create","summary":"Submit an expense for an employee","description":"Requires write:payroll_requests. Submits an expense as pending for a manager to approve in WildPipe. Requires unrestricted company access. Retrying with the same Idempotency-Key and identical content returns the original result without repeating the change. Recover a lost response with GET /operations/expense_create/{key}.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["user_id","category","amount"],"properties":{"user_id":{"type":"string","format":"uuid"},"category":{"type":"string","minLength":1,"maxLength":100},"amount":{"type":"number","exclusiveMinimum":0,"maximum":50000,"multipleOf":0.01},"vendor":{"type":"string","maxLength":200,"nullable":true},"description":{"type":"string","maxLength":2000,"nullable":true},"expense_date":{"type":"string","format":"date"},"job_id":{"type":"string","format":"uuid"},"is_billable":{"type":"boolean"},"payment_method":{"type":"string","maxLength":50,"nullable":true}}}}}},"responses":{"200":{"description":"Original result of an identical retry (replayed true)"},"201":{"description":"Committed; data holds the result and replayed is false"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Expenses"]}},"/expenses/{id}":{"get":{"operationId":"get_expenses","summary":"Get one: employee expenses","description":"Requires read:payroll. Returns one record with the same fields as the list.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Expenses"]}},"/time_off_requests":{"get":{"operationId":"list_time_off_requests","summary":"Time-off requests","description":"Requires read:payroll. Returned fields: id, user_id, pto_type, start_date, end_date, hours_requested, status, reason, reviewed_by, reviewed_at, created_at, updated_at. Pages are ordered by ID; filters and company access bind the cursor. Organization-wide: requires an unrestricted company grant. updated_at reports the creation time for records unchanged since change tracking began, so updated_from also returns records created in the window.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":4096},"description":"Opaque next_cursor; repeat the same filters on every page."},{"name":"user_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Time Off Requests"]},"post":{"operationId":"time_off_create","summary":"Request time off for an employee","description":"Requires write:payroll_requests. Submits a time-off request as pending for a manager to review in WildPipe. Requires unrestricted company access. Retrying with the same Idempotency-Key and identical content returns the original result without repeating the change. Recover a lost response with GET /operations/time_off_create/{key}.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["user_id","pto_type","start_date","end_date","hours_requested"],"properties":{"user_id":{"type":"string","format":"uuid"},"pto_type":{"type":"string","enum":["vacation","sick","personal","parental"]},"start_date":{"type":"string","format":"date"},"end_date":{"type":"string","format":"date"},"hours_requested":{"type":"number","minimum":0.25,"maximum":3000},"reason":{"type":"string","maxLength":2000,"nullable":true}}}}}},"responses":{"200":{"description":"Original result of an identical retry (replayed true)"},"201":{"description":"Committed; data holds the result and replayed is false"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Time Off Requests"]}},"/time_off_requests/{id}":{"get":{"operationId":"get_time_off_requests","summary":"Get one: time-off requests","description":"Requires read:payroll. Returns one record with the same fields as the list.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Time Off Requests"]}},"/reimbursements":{"get":{"operationId":"list_reimbursements","summary":"Employee reimbursements","description":"Requires read:payroll. Returned fields: id, user_id, job_id, description, amount, status, paid_at, submitted_at, created_at, updated_at. Pages are ordered by ID; filters and company access bind the cursor. Organization-wide: requires an unrestricted company grant. updated_at reports the creation time for records unchanged since change tracking began, so updated_from also returns records created in the window.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":4096},"description":"Opaque next_cursor; repeat the same filters on every page."},{"name":"user_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"job_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Reimbursements"]}},"/reimbursements/{id}":{"get":{"operationId":"get_reimbursements","summary":"Get one: employee reimbursements","description":"Requires read:payroll. Returns one record with the same fields as the list.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Reimbursements"]}},"/campaigns":{"get":{"operationId":"list_campaigns","summary":"Marketing campaigns and their results","description":"Requires read:marketing. Returned fields: id, company_id, name, description, channel, status, sms_template, email_subject, email_body, scheduled_at, started_at, completed_at, total_recipients, sent_count, delivered_count, failed_count, opened_count, clicked_count, unsubscribed_count, created_at, updated_at. Pages are ordered by ID; filters and company access bind the cursor. Company-restricted keys see only records of their companies. updated_at reports the creation time for records unchanged since change tracking began, so updated_from also returns records created in the window.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":4096},"description":"Opaque next_cursor; repeat the same filters on every page."},{"name":"company_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Campaigns"]}},"/campaigns/{id}":{"get":{"operationId":"get_campaigns","summary":"Get one: marketing campaigns and their results","description":"Requires read:marketing. Returns one record with the same fields as the list.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Campaigns"]}},"/automations":{"get":{"operationId":"list_automations","summary":"Automation sequences","description":"Requires read:marketing. Returned fields: id, name, description, trigger_type, is_active, created_at, updated_at. Pages are ordered by ID; filters and company access bind the cursor. Organization-wide: requires an unrestricted company grant. updated_at reports the creation time for records unchanged since change tracking began, so updated_from also returns records created in the window.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":4096},"description":"Opaque next_cursor; repeat the same filters on every page."},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Automations"]}},"/automations/{id}":{"get":{"operationId":"get_automations","summary":"Get one: automation sequences","description":"Requires read:marketing. Returns one record with the same fields as the list.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Automations"]}},"/forms":{"get":{"operationId":"list_forms","summary":"Website contact forms and their fields","description":"Requires read:marketing. Returned fields: id, company_id, name, description, fields_config, is_active, created_at, updated_at. Pages are ordered by ID; filters and company access bind the cursor. Company-restricted keys see only records of their companies. updated_at reports the creation time for records unchanged since change tracking began, so updated_from also returns records created in the window.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":4096},"description":"Opaque next_cursor; repeat the same filters on every page."},{"name":"company_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Forms"]}},"/forms/{id}":{"get":{"operationId":"get_forms","summary":"Get one: website contact forms and their fields","description":"Requires read:marketing. Returns one record with the same fields as the list.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Forms"]}},"/booking_widgets":{"get":{"operationId":"list_booking_widgets","summary":"Online booking widgets","description":"Requires read:marketing. Returned fields: id, company_id, name, is_active, allowed_services, min_notice_hours, max_days_ahead, min_deposit_amount, collect_contact_first, created_at, updated_at. Pages are ordered by ID; filters and company access bind the cursor. Company-restricted keys see only records of their companies. updated_at reports the creation time for records unchanged since change tracking began, so updated_from also returns records created in the window.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":4096},"description":"Opaque next_cursor; repeat the same filters on every page."},{"name":"company_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Booking Widgets"]}},"/booking_widgets/{id}":{"get":{"operationId":"get_booking_widgets","summary":"Get one: online booking widgets","description":"Requires read:marketing. Returns one record with the same fields as the list.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Booking Widgets"]}},"/chat_widgets":{"get":{"operationId":"list_chat_widgets","summary":"Website chat widgets","description":"Requires read:marketing. Returned fields: id, company_id, name, website_url, is_active, created_at, updated_at. Pages are ordered by ID; filters and company access bind the cursor. Company-restricted keys see only records of their companies. updated_at reports the creation time for records unchanged since change tracking began, so updated_from also returns records created in the window.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":4096},"description":"Opaque next_cursor; repeat the same filters on every page."},{"name":"company_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Chat Widgets"]}},"/chat_widgets/{id}":{"get":{"operationId":"get_chat_widgets","summary":"Get one: website chat widgets","description":"Requires read:marketing. Returns one record with the same fields as the list.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Chat Widgets"]}},"/contractors":{"get":{"operationId":"list_contractors","summary":"Contractor businesses","description":"Requires read:contractors. Returned fields: id, business_name, first_name, last_name, email, phone, capabilities, service_areas, status, created_at, updated_at, app_url. Pages are ordered by ID; filters and company access bind the cursor. Organization-wide: requires an unrestricted company grant. updated_at reports the creation time for records unchanged since change tracking began, so updated_from also returns records created in the window. app_url opens the contractor’s own page in WildPipe.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":4096},"description":"Opaque next_cursor; repeat the same filters on every page."},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Contractors"]}},"/contractors/{id}":{"get":{"operationId":"get_contractors","summary":"Get one: contractor businesses","description":"Requires read:contractors. Returns one record with the same fields as the list.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Contractors"]}},"/contractor_work_orders":{"get":{"operationId":"list_contractor_work_orders","summary":"Contractor work orders","description":"Requires read:contractors. Returned fields: id, contractor_id, company_id, job_id, quote_id, title, instructions, compensation, currency, status, created_at, updated_at. Pages are ordered by ID; filters and company access bind the cursor. Company-restricted keys see only records of their companies. updated_at reports the creation time for records unchanged since change tracking began, so updated_from also returns records created in the window.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":4096},"description":"Opaque next_cursor; repeat the same filters on every page."},{"name":"company_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"job_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"contractor_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Contractor Work Orders"]}},"/contractor_work_orders/{id}":{"get":{"operationId":"get_contractor_work_orders","summary":"Get one: contractor work orders","description":"Requires read:contractors. Returns one record with the same fields as the list.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Contractor Work Orders"]}},"/corporate_accounts":{"get":{"operationId":"list_corporate_accounts","summary":"Property manager accounts","description":"Requires read:corporate_accounts. Returned fields: id, company_id, name, status, account_contact_id, billing_contact_id, auto_pay_enabled, settings, version, created_at, updated_at. Pages are ordered by ID; filters and company access bind the cursor. Company-restricted keys see only records of their companies. updated_at reports the creation time for records unchanged since change tracking began, so updated_from also returns records created in the window.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":4096},"description":"Opaque next_cursor; repeat the same filters on every page."},{"name":"company_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Property Accounts"]}},"/corporate_accounts/{id}":{"get":{"operationId":"get_corporate_accounts","summary":"Get one: property manager accounts","description":"Requires read:corporate_accounts. Returns one record with the same fields as the list.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Property Accounts"]}},"/corporate_sites":{"get":{"operationId":"list_corporate_sites","summary":"Buildings on property accounts","description":"Requires read:corporate_accounts. Returned fields: id, account_id, name, address, is_active, created_at, updated_at, company_id. Pages are ordered by ID; filters and company access bind the cursor. Company-restricted keys see only records of their companies. updated_at reports the creation time for records unchanged since change tracking began, so updated_from also returns records created in the window.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":4096},"description":"Opaque next_cursor; repeat the same filters on every page."},{"name":"account_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Property Accounts"]}},"/corporate_sites/{id}":{"get":{"operationId":"get_corporate_sites","summary":"Get one: buildings on property accounts","description":"Requires read:corporate_accounts. Returns one record with the same fields as the list.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Property Accounts"]}},"/corporate_units":{"get":{"operationId":"list_corporate_units","summary":"Units on property accounts","description":"Requires read:corporate_accounts. Returned fields: id, account_id, site_id, label, unit_type, address, payer_override, is_active, created_at, updated_at, company_id. Pages are ordered by ID; filters and company access bind the cursor. Company-restricted keys see only records of their companies. updated_at reports the creation time for records unchanged since change tracking began, so updated_from also returns records created in the window.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":4096},"description":"Opaque next_cursor; repeat the same filters on every page."},{"name":"account_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"site_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Property Accounts"]}},"/corporate_units/{id}":{"get":{"operationId":"get_corporate_units","summary":"Get one: units on property accounts","description":"Requires read:corporate_accounts. Returns one record with the same fields as the list.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Property Accounts"]},"patch":{"operationId":"corporate_unit_update","summary":"Change a unit","description":"Requires write:corporate_accounts. Changes a unit's label, building, address, who pays, notes or whether it is active. Open unpaid invoices and unaccepted quotes follow a change in who pays. Retrying with the same Idempotency-Key and identical content returns the original result without repeating the change. Recover a lost response with GET /operations/corporate_unit_update/{key}.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["expected_updated_at"],"properties":{"expected_updated_at":{"type":"string","format":"date-time","description":"The updated_at you last read. A newer value is refused with 409."},"site_id":{"type":"string","format":"uuid","nullable":true},"label":{"type":"string","minLength":1,"maxLength":120},"address":{"type":"string","maxLength":300,"nullable":true},"payer_override":{"type":"string","enum":["account","tenant",""],"description":"Who pays for this unit's work; empty uses the account rules."},"notes":{"type":"string","maxLength":2000,"nullable":true},"is_active":{"type":"boolean"}}}}}},"responses":{"200":{"description":"Committed, or the original result of an identical retry"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Property Accounts"]}},"/corporate_team_members":{"get":{"operationId":"list_corporate_team_members","summary":"Property account team members","description":"Requires read:corporate_accounts. Returned fields: id, account_id, contact_id, role, site_ids, status, removed_at, created_at, updated_at, company_id. Pages are ordered by ID; filters and company access bind the cursor. Company-restricted keys see only records of their companies. updated_at reports the creation time for records unchanged since change tracking began, so updated_from also returns records created in the window.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":4096},"description":"Opaque next_cursor; repeat the same filters on every page."},{"name":"account_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"contact_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Property Accounts"]}},"/corporate_team_members/{id}":{"get":{"operationId":"get_corporate_team_members","summary":"Get one: property account team members","description":"Requires read:corporate_accounts. Returns one record with the same fields as the list.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Property Accounts"]}},"/corporate_tenancies":{"get":{"operationId":"list_corporate_tenancies","summary":"Current and former tenants of units","description":"Requires read:corporate_accounts. Returned fields: id, account_id, unit_id, contact_id, is_primary, status, portal_access, move_in_date, move_out_date, end_reason, created_at, updated_at, company_id. Pages are ordered by ID; filters and company access bind the cursor. Company-restricted keys see only records of their companies. updated_at reports the creation time for records unchanged since change tracking began, so updated_from also returns records created in the window.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":4096},"description":"Opaque next_cursor; repeat the same filters on every page."},{"name":"account_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"unit_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"contact_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Property Accounts"]}},"/corporate_tenancies/{id}":{"get":{"operationId":"get_corporate_tenancies","summary":"Get one: current and former tenants of units","description":"Requires read:corporate_accounts. Returns one record with the same fields as the list.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Property Accounts"]}},"/corporate_requests":{"get":{"operationId":"list_corporate_requests","summary":"Service requests from property accounts and tenants","description":"Requires read:corporate_accounts. Returned fields: id, account_id, unit_id, requested_by_contact_id, tenant_contact_id, service_id, service_name, description, preferred_date, preferred_window, status, payer, source, approval_mode, decided_at, decision_note, job_id, created_at, updated_at, company_id. Pages are ordered by ID; filters and company access bind the cursor. Company-restricted keys see only records of their companies. updated_at reports the creation time for records unchanged since change tracking began, so updated_from also returns records created in the window.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":4096},"description":"Opaque next_cursor; repeat the same filters on every page."},{"name":"account_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"unit_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"job_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Property Accounts"]}},"/corporate_requests/{id}":{"get":{"operationId":"get_corporate_requests","summary":"Get one: service requests from property accounts and tenants","description":"Requires read:corporate_accounts. Returns one record with the same fields as the list.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Property Accounts"]}},"/corporate_unit_prices":{"get":{"operationId":"list_corporate_unit_prices","summary":"Contract prices by unit type on property accounts (one-time, plan and charge prices)","description":"Requires read:corporate_accounts. Returned fields: id, account_id, unit_type, service_id, price_kind, pricing_rule_id, price, version, created_at, updated_at, company_id. Pages are ordered by ID; filters and company access bind the cursor. Company-restricted keys see only records of their companies. updated_at reports the creation time for records unchanged since change tracking began, so updated_from also returns records created in the window.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":4096},"description":"Opaque next_cursor; repeat the same filters on every page."},{"name":"account_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"service_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"price_kind","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Property Accounts"]}},"/corporate_unit_prices/{id}":{"get":{"operationId":"get_corporate_unit_prices","summary":"Get one: contract prices by unit type on property accounts (one-time, plan and charge prices)","description":"Requires read:corporate_accounts. Returns one record with the same fields as the list.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Property Accounts"]}},"/property_keys":{"get":{"operationId":"list_property_keys","summary":"Physical customer keys and who holds them","description":"Requires read:properties. Returned fields: id, company_id, contact_id, contact_address_id, tag_number, key_type, description, status, holder_user_id, checked_out_at, due_back_at, storage_location, version, created_at, updated_at. Pages are ordered by ID; filters and company access bind the cursor. Company-restricted keys see only records of their companies. updated_at reports the creation time for records unchanged since change tracking began, so updated_from also returns records created in the window.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":4096},"description":"Opaque next_cursor; repeat the same filters on every page."},{"name":"company_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"contact_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Properties"]}},"/property_keys/{id}":{"get":{"operationId":"get_property_keys","summary":"Get one: physical customer keys and who holds them","description":"Requires read:properties. Returns one record with the same fields as the list.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Properties"]}},"/property_key_events":{"get":{"operationId":"list_property_key_events","summary":"Key sign-out and return history","description":"Requires read:properties. Returned fields: id, key_id, action, actor_id, holder_user_id, task_id, note, created_at, updated_at, company_id. Pages are ordered by ID; filters and company access bind the cursor. Company-restricted keys see only records of their companies. updated_at reports the creation time for records unchanged since change tracking began, so updated_from also returns records created in the window.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":4096},"description":"Opaque next_cursor; repeat the same filters on every page."},{"name":"key_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"task_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Properties"]}},"/property_key_events/{id}":{"get":{"operationId":"get_property_key_events","summary":"Get one: key sign-out and return history","description":"Requires read:properties. Returns one record with the same fields as the list.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Properties"]}},"/service_reports":{"get":{"operationId":"list_service_reports","summary":"Service reports sent to customers after visits (no report links)","description":"Requires read:field_records and read:tasks. Returned fields: id, company_id, task_id, job_id, contact_id, technician_id, survey_id, status, channels, skip_reason, sent_at, first_viewed_at, view_count, created_at, updated_at. Pages are ordered by ID; filters and company access bind the cursor. Company-restricted keys see only records of their companies. updated_at reports the creation time for records unchanged since change tracking began, so updated_from also returns records created in the window.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":4096},"description":"Opaque next_cursor; repeat the same filters on every page."},{"name":"company_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"task_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"job_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"contact_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Field & Compliance"]}},"/service_reports/{id}":{"get":{"operationId":"get_service_reports","summary":"Get one: service reports sent to customers after visits (no report links)","description":"Requires read:field_records and read:tasks. Returns one record with the same fields as the list.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Field & Compliance"]}},"/service_report_settings":{"get":{"operationId":"list_service_report_settings","summary":"Service report settings (organization default has no company; company rows override it)","description":"Requires read:field_records and read:tasks. Returned fields: id, company_id, enabled, channel, include_rating, include_photos, include_technician_notes, include_treatments, include_devices, low_rating_threshold, appointments_only, version, created_at, updated_at. Pages are ordered by ID; filters and company access bind the cursor. Company-restricted keys see only records of their companies.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":4096},"description":"Opaque next_cursor; repeat the same filters on every page."},{"name":"company_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Service Report Settings"]}},"/service_report_settings/{id}":{"get":{"operationId":"get_service_report_settings","summary":"Get one: service report settings (organization default has no company; company rows override it)","description":"Requires read:field_records and read:tasks. Returns one record with the same fields as the list.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Service Report Settings"]}},"/card_expiry_notices":{"get":{"operationId":"list_card_expiry_notices","summary":"Card-expiry warnings sent to auto-pay customers (no card details)","description":"Requires read:payments. Returned fields: id, contact_id, stage, channels, status, created_at, updated_at, company_id. Pages are ordered by ID; filters and company access bind the cursor. Company-restricted keys see only records of their companies. updated_at reports the creation time for records unchanged since change tracking began, so updated_from also returns records created in the window.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":4096},"description":"Opaque next_cursor; repeat the same filters on every page."},{"name":"contact_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Card Expiry Notices"]}},"/card_expiry_notices/{id}":{"get":{"operationId":"get_card_expiry_notices","summary":"Get one: card-expiry warnings sent to auto-pay customers (no card details)","description":"Requires read:payments. Returns one record with the same fields as the list.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Card Expiry Notices"]}},"/price_change_batches":{"get":{"operationId":"list_price_change_batches","summary":"Plan price increase batches","description":"Requires read:details and read:jobs. Returned fields: id, company_id, name, change_type, change_value, rounding, effective_date, notice_days, customer_message, status, plan_count, monthly_increase, created_by, created_at, updated_at. Pages are ordered by ID; filters and company access bind the cursor. Company-restricted keys see only records of their companies. updated_at reports the creation time for records unchanged since change tracking began, so updated_from also returns records created in the window.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":4096},"description":"Opaque next_cursor; repeat the same filters on every page."},{"name":"company_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Plan Pricing"]}},"/price_change_batches/{id}":{"get":{"operationId":"get_price_change_batches","summary":"Get one: plan price increase batches","description":"Requires read:details and read:jobs. Returns one record with the same fields as the list.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Plan Pricing"]}},"/plan_price_changes":{"get":{"operationId":"list_plan_price_changes","summary":"Scheduled and applied plan price changes","description":"Requires read:details and read:jobs. Returned fields: id, batch_id, company_id, job_id, contact_id, old_price, new_price, effective_date, notice_due_date, notice_status, notice_channels, notice_sent_at, status, applied_at, cancelled_reason, created_at, updated_at. Pages are ordered by ID; filters and company access bind the cursor. Company-restricted keys see only records of their companies. updated_at reports the creation time for records unchanged since change tracking began, so updated_from also returns records created in the window.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":4096},"description":"Opaque next_cursor; repeat the same filters on every page."},{"name":"company_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"job_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"contact_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"batch_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Plan Pricing"]}},"/plan_price_changes/{id}":{"get":{"operationId":"get_plan_price_changes","summary":"Get one: scheduled and applied plan price changes","description":"Requires read:details and read:jobs. Returns one record with the same fields as the list.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Plan Pricing"]}},"/plan_renewal_notices":{"get":{"operationId":"list_plan_renewal_notices","summary":"Plan renewal reminders sent to customers","description":"Requires read:details and read:jobs. Returned fields: id, job_id, commitment_end_date, channels, status, created_at, updated_at, company_id. Pages are ordered by ID; filters and company access bind the cursor. Company-restricted keys see only records of their companies. updated_at reports the creation time for records unchanged since change tracking began, so updated_from also returns records created in the window.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":4096},"description":"Opaque next_cursor; repeat the same filters on every page."},{"name":"job_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Plan Pricing"]}},"/plan_renewal_notices/{id}":{"get":{"operationId":"get_plan_renewal_notices","summary":"Get one: plan renewal reminders sent to customers","description":"Requires read:details and read:jobs. Returns one record with the same fields as the list.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Plan Pricing"]}},"/monitoring_points":{"get":{"operationId":"list_monitoring_points","summary":"Monitored traps, bait stations, cameras, sensors and inspection spots","description":"Requires read:monitoring. Returned fields: id, company_id, contact_id, job_id, label, code, point_type, zone, target_pests, site_map_id, map_x, map_y, bait_station_id, trap_id, sensor_id, camera_id, is_active, installed_at, removed_at, notes, created_at, updated_at. Pages are ordered by ID; filters and company access bind the cursor. Company-restricted keys see only records of their companies.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":4096},"description":"Opaque next_cursor; repeat the same filters on every page."},{"name":"company_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"contact_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"job_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Activity Monitoring"]}},"/monitoring_points/{id}":{"get":{"operationId":"get_monitoring_points","summary":"Get one: monitored traps, bait stations, cameras, sensors and inspection spots","description":"Requires read:monitoring. Returns one record with the same fields as the list.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Activity Monitoring"]}},"/activity_observations":{"get":{"operationId":"list_activity_observations","summary":"Pest and animal activity records (a correction is a new record that names the one it replaces)","description":"Requires read:monitoring. Returned fields: id, company_id, contact_id, job_id, point_id, source_kind, source_id, observation, pest_group, species, quantity, severity, trust, customer_visible, summary, observed_at, recorded_at, corrects_id, voided, created_at, updated_at. Pages are ordered by ID; filters and company access bind the cursor. Company-restricted keys see only records of their companies. updated_at reports the creation time for records unchanged since change tracking began, so updated_from also returns records created in the window.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":4096},"description":"Opaque next_cursor; repeat the same filters on every page."},{"name":"company_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"contact_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"job_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"point_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"observation","in":"query","schema":{"type":"string","maxLength":120},"description":"Exact match."},{"name":"pest_group","in":"query","schema":{"type":"string","maxLength":120},"description":"Exact match."},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Activity Monitoring"]}},"/activity_observations/{id}":{"get":{"operationId":"get_activity_observations","summary":"Get one: pest and animal activity records (a correction is a new record that names the one it replaces)","description":"Requires read:monitoring. Returns one record with the same fields as the list.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Activity Monitoring"]}},"/monitoring_actions":{"get":{"operationId":"list_monitoring_actions","summary":"Corrective actions opened from activity","description":"Requires read:monitoring. Returned fields: id, company_id, contact_id, job_id, point_id, observation_id, category, title, details, root_cause, action_plan, responsible, priority, status, due_date, completed_at, completion_notes, verified_at, customer_visible, customer_ack_at, customer_ack_name, customer_response, created_at, updated_at. Pages are ordered by ID; filters and company access bind the cursor. Company-restricted keys see only records of their companies.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":4096},"description":"Opaque next_cursor; repeat the same filters on every page."},{"name":"company_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"contact_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"job_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"point_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"status","in":"query","schema":{"type":"string","maxLength":120},"description":"Exact match."},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Activity Monitoring"]}},"/monitoring_actions/{id}":{"get":{"operationId":"get_monitoring_actions","summary":"Get one: corrective actions opened from activity","description":"Requires read:monitoring. Returns one record with the same fields as the list.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Activity Monitoring"]}},"/monitoring_reports":{"get":{"operationId":"list_monitoring_reports","summary":"Saved activity reports and audit packets (summary details; open the full report in the app)","description":"Requires read:monitoring. Returned fields: id, company_id, contact_id, corporate_account_id, report_kind, scope_type, scope_id, title, standard, period_start, period_end, customer_visible, generated_via, email_status, emailed_at, created_at, updated_at. Pages are ordered by ID; filters and company access bind the cursor. Company-restricted keys see only records of their companies. updated_at reports the creation time for records unchanged since change tracking began, so updated_from also returns records created in the window.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":4096},"description":"Opaque next_cursor; repeat the same filters on every page."},{"name":"company_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"contact_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"corporate_account_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"report_kind","in":"query","schema":{"type":"string","maxLength":120},"description":"Exact match."},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Activity Monitoring"]}},"/monitoring_reports/{id}":{"get":{"operationId":"get_monitoring_reports","summary":"Get one: saved activity reports and audit packets (summary details; open the full report in the app)","description":"Requires read:monitoring. Returns one record with the same fields as the list.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Activity Monitoring"]}},"/sales_contests":{"get":{"operationId":"list_sales_contests","summary":"Sales contests (unrestricted keys)","description":"Requires read:employees. Returned fields: id, company_ids, name, description, metric, group_by, starts_on, ends_on, prize, show_amounts, status, version, created_by, cancelled_at, created_at, updated_at. Pages are ordered by ID; filters and company access bind the cursor. Organization-wide: requires an unrestricted company grant. updated_at reports the creation time for records unchanged since change tracking began, so updated_from also returns records created in the window.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string","maxLength":4096},"description":"Opaque next_cursor; repeat the same filters on every page."},{"name":"updated_from","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."},{"name":"updated_to","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight, on updated_at."}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Employees"]}},"/sales_contests/{id}":{"get":{"operationId":"get_sales_contests","summary":"Get one: sales contests (unrestricted keys)","description":"Requires read:employees. Returns one record with the same fields as the list.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Employees"]}},"/documents/{id}/download":{"get":{"operationId":"download_customer_document","summary":"Private customer document download","description":"Requires read:documents AND read:document_files. A separate explicitly approved file permission is never inferred from metadata access. Only non-archived customer-linked files with every linked record inside tenant/company access are eligible; employee and contractor files are excluded. Returns an audited five-minute bearer URL, not a public file or durable storage path. Treat the URL as sensitive. Already issued URLs remain usable until expiry; revocation denies new links but cannot recall shared content. No query parameters.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Five-minute private download URL; response is no-store","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"file_name":{"type":"string"},"download_url":{"type":"string","format":"uri"},"expires_in":{"type":"integer","enum":[300]}},"required":["id","file_name","download_url","expires_in"]}},"required":["data"]}}}},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Documents"]}},"/contacts/{id}/details":{"get":{"operationId":"get_contacts_details","summary":"Detailed contacts","description":"Requires read:contacts AND read:details. No signature URL, processor credentials, internal cost breakdowns or implicit notes/transcript export. Line-item order is preserved.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Customers"]}},"/companies/{id}/details":{"get":{"operationId":"get_companies_details","summary":"Detailed companies","description":"Requires read:companies AND read:details. No signature URL, processor credentials, internal cost breakdowns or implicit notes/transcript export. Line-item order is preserved.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Companies"]}},"/jobs/{id}/details":{"get":{"operationId":"get_jobs_details","summary":"Detailed jobs","description":"Requires read:jobs AND read:details. No signature URL, processor credentials, internal cost breakdowns or implicit notes/transcript export. Line-item order is preserved.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Jobs"]},"patch":{"operationId":"job_update","summary":"Change a job's service type or property","description":"Requires write:jobs. Changes appointment_type and/or moves the job to another saved property of its customer. Open visits and active cameras follow the new property, visit history records the change and assigned routes are refreshed. Closed jobs are refused. Edit job notes with PATCH /jobs/{id}; change phase with POST /jobs/{id}/phase. Retrying with the same Idempotency-Key and identical content returns the original result without repeating the change. Recover a lost response with GET /operations/job_update/{key}.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["expected_updated_at"],"properties":{"expected_updated_at":{"type":"string","format":"date-time","description":"The updated_at you last read. A newer value is refused with 409."},"appointment_type":{"type":"string","maxLength":100,"nullable":true},"service_address_id":{"type":"string","format":"uuid"}}}}}},"responses":{"200":{"description":"Committed, or the original result of an identical retry"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Jobs"]}},"/tasks/{id}/details":{"get":{"operationId":"get_tasks_details","summary":"Detailed tasks","description":"Requires read:tasks AND read:details. No signature URL, processor credentials, internal cost breakdowns or implicit notes/transcript export. Line-item order is preserved.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Tasks & Visits"]}},"/quotes/{id}/details":{"get":{"operationId":"get_quotes_details","summary":"Detailed quotes","description":"Requires read:quotes AND read:details. No signature URL, processor credentials, internal cost breakdowns or implicit notes/transcript export. Line-item order is preserved.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Quotes"]}},"/invoices/{id}/details":{"get":{"operationId":"get_invoices_details","summary":"Detailed invoices","description":"Requires read:invoices AND read:details. No signature URL, processor credentials, internal cost breakdowns or implicit notes/transcript export. Line-item order is preserved.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Invoices"]}},"/products/{id}/details":{"get":{"operationId":"get_products_details","summary":"Detailed products","description":"Requires read:products AND read:details. No signature URL, processor credentials, internal cost breakdowns or implicit notes/transcript export. Line-item order is preserved.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Products"]}},"/services/{id}/details":{"get":{"operationId":"get_services_details","summary":"Detailed services","description":"Requires read:services AND read:details. No signature URL, processor credentials, internal cost breakdowns or implicit notes/transcript export. Line-item order is preserved.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Services"]}},"/quotes/{id}/items":{"get":{"operationId":"get_quotes_items","summary":"Customer line items in authored order","description":"Requires read:quotes AND read:details. Internal economics excluded.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Quotes"]}},"/invoices/{id}/items":{"get":{"operationId":"get_invoices_items","summary":"Customer line items in authored order","description":"Requires read:invoices AND read:details. Internal economics excluded.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Invoices"]}},"/contacts/{id}/activity":{"get":{"operationId":"get_contacts_notes","summary":"Read authored notes","description":"Requires read:contacts AND read:activity. At most 100, with complete flag. No transcript export. Contact-wide notes require an unrestricted company grant.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Customers"]}},"/jobs/{id}/activity":{"get":{"operationId":"get_jobs_notes","summary":"Read authored notes","description":"Requires read:jobs AND read:activity. At most 100, with complete flag. No transcript export. Contact-wide notes require an unrestricted company grant.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Jobs"]}},"/tasks/{id}/activity":{"get":{"operationId":"get_tasks_notes","summary":"Read authored notes","description":"Requires read:tasks AND read:activity. At most 100, with complete flag. No transcript export. Contact-wide notes require an unrestricted company grant.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Tasks & Visits"]}},"/contacts/{id}/addresses":{"get":{"operationId":"get_contact_properties","summary":"Saved customer properties","description":"Requires read:contacts AND read:properties. At most 100; use /properties?contact_id= for cursor pagination.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Customers"]},"post":{"operationId":"add_customer_property","summary":"Add a saved property","description":"Requires write:properties. Explicit new permission; existing grants are unchanged. Target, exact bytes and Idempotency-Key are bound to the stored receipt. No consent or company overrides.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["address"],"properties":{"address":{"type":"string","minLength":5,"maxLength":500},"address_line2":{"type":"string","nullable":true,"maxLength":200}}}}}},"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Customers"]}},"/invoices/{id}/allocations":{"get":{"operationId":"get_invoices_allocations","summary":"Actual invoice payment allocations","description":"Requires read:invoices AND read:details. At most 100, with complete flag; both sides stay tenant/company scoped.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Invoices"]}},"/payments/{id}/allocations":{"get":{"operationId":"get_payments_allocations","summary":"Actual invoice payment allocations","description":"Requires read:payments AND read:details. At most 100, with complete flag; both sides stay tenant/company scoped.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Payments"]},"post":{"operationId":"allocate_existing_payment","summary":"Allocate an existing succeeded payment to reviewed unpaid invoices of the same customer and company. Supply the COMPLETE existing allocation set and each invoice’s observed total, paid amount and status. No new charge, fee, refund, discount or payment is recorded. Invoice balances update automatically.","description":"Requires write:payment_allocations and unrestricted company access. Allocate an existing succeeded payment to reviewed unpaid invoices of the same customer and company. Supply the COMPLETE existing allocation set and each invoice’s observed total, paid amount and status. No new charge, fee, refund, discount or payment is recorded. Invoice balances update automatically. JSON limit 64 KiB. The reviewed values, an audit record and the receipt are saved with the change. A 409 means reviewed state or retry identity changed; review before a new request. Never automatically replay an uncertain result under a new identity.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["expected_payment_amount","expected_allocations","allocations"],"properties":{"expected_payment_amount":{"type":"number","minimum":0,"maximum":999999999,"multipleOf":0.01},"expected_allocations":{"type":"array","maxItems":100,"items":{"type":"object","additionalProperties":false,"required":["invoice_id","amount_allocated"],"properties":{"invoice_id":{"type":"string","format":"uuid"},"amount_allocated":{"type":"number","minimum":0,"maximum":999999999,"multipleOf":0.01,"exclusiveMinimum":true}}}},"allocations":{"type":"array","minItems":1,"maxItems":50,"items":{"type":"object","additionalProperties":false,"required":["invoice_id","amount_allocated","expected_total","expected_amount_paid","expected_status"],"properties":{"invoice_id":{"type":"string","format":"uuid"},"amount_allocated":{"type":"number","minimum":0,"maximum":999999999,"multipleOf":0.01,"exclusiveMinimum":true},"expected_total":{"type":"number","minimum":0,"maximum":999999999,"multipleOf":0.01},"expected_amount_paid":{"type":"number","minimum":0,"maximum":999999999,"multipleOf":0.01},"expected_status":{"type":"string","minLength":1,"maxLength":80}}}}}}}}},"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Payments"]}},"/jobs/{id}/authored-notes":{"get":{"operationId":"get_job_authored_notes","summary":"Review authored job notes and timestamp","description":"Requires read:jobs AND read:activity and unrestricted company access. Returns id, company_id, updated_at, notes and can_edit; not timeline notes or transcripts. No query parameters.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Jobs"]}},"/operations/job_notes/{key}":{"get":{"operationId":"get_job_note_operation","summary":"Read this connection’s committed job-note outcome","description":"Requires write:job_notes and unrestricted company access. Historical outcome only; no note text. Missing does not prove an in-flight request failed.","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Receipts"]}},"/booking-holds":{"post":{"operationId":"reserve_booking_hold","summary":"Temporarily reserve a live opening","description":"Requires separately approved write:booking_holds and unrestricted company access. One-time company-widget openings only. No booking, payment, consent or notification. No query parameters. JSON limit 4 KiB. Rechecks that the exact opening is still available when the hold is placed. Expires after ten minutes. Exact retries return the original receipt, never renew an expired/released hold. Optional booking_hold_id on appointment creation uses this connection’s matching active hold and also requires write:appointments.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["widget_id","service_id","date","slot_label"],"properties":{"widget_id":{"type":"string","format":"uuid"},"service_id":{"type":"string","format":"uuid"},"date":{"type":"string","format":"date"},"slot_label":{"type":"string","minLength":1,"maxLength":50}}}}}},"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Booking Holds"]}},"/booking-holds/{id}":{"get":{"operationId":"get_booking_hold","summary":"Current connection-owned hold status","description":"Requires separately approved write:booking_holds and unrestricted company access. One-time company-widget openings only. No booking, payment, consent or notification. No query parameters. Expired/released/not_retained means no reservation remains. Use current status, not the historical reserve receipt.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Booking Holds"]},"delete":{"operationId":"release_booking_hold","summary":"Release only this connection’s own hold","description":"Requires separately approved write:booking_holds and unrestricted company access. One-time company-widget openings only. No booking, payment, consent or notification. No query parameters. Requires a distinct release Idempotency-Key and no body. Converted holds cannot be released; booked appointments are never cancelled. The release, its audit record and the receipt are saved together.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Booking Holds"]}},"/operations/booking_hold/{key}":{"get":{"operationId":"get_booking_hold_operation","summary":"Original reserve/release receipt","description":"Requires separately approved write:booking_holds and unrestricted company access. One-time company-widget openings only. No booking, payment, consent or notification. No query parameters. Historical commit only, not current hold status. Missing does not prove an in-flight request failed.","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Receipts"]}},"/contacts/{id}/identity":{"put":{"operationId":"update_customer_identity","summary":"Update customer identity","description":"Requires write:identity. Explicit new permission; existing grants are unchanged. Target, exact bytes and Idempotency-Key are bound to the stored receipt. No consent or company overrides.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"minProperties":1,"properties":{"first_name":{"type":"string","nullable":true,"maxLength":100},"last_name":{"type":"string","nullable":true,"maxLength":100},"email":{"type":"string","nullable":true,"maxLength":254},"phone":{"type":"string","nullable":true,"maxLength":40}}}}}},"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Customers"]}},"/contacts/{id}/addresses/{addressId}":{"patch":{"operationId":"correct_customer_property","summary":"Correct a saved property","description":"Requires write:property_updates and unrestricted company access. The property keeps its ID. The correction also updates open work and documents that used the exact old address; completed visits and prices are never changed. Supply the last-read updated_at. Street corrections clear stale coordinates until geocoded. 409 means conflicting bytes/target or a changed property; review current state before a new request.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"addressId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["address","expected_updated_at"],"properties":{"address":{"type":"string","minLength":5,"maxLength":500},"address_line2":{"type":"string","nullable":true,"maxLength":200},"expected_updated_at":{"type":"string","format":"date-time"}}}}}},"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Customers"]}},"/contacts/{id}/tags":{"put":{"operationId":"update_contacts_tags","summary":"Update direct tag assignments","description":"Requires write:tag_assignments. Supply complete current direct tag IDs as expected_tag_ids. Add preserves existing tags; replace may remove them. Contact changes and explicit shared-to-primary-contact propagation require unrestricted company access. Only both-scope tags propagate, additively; related job tags never become direct safety flags implicitly. The update, its audit record and the receipt are saved together. 409 requires reviewing latest state.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["tag_ids","expected_tag_ids","mode"],"properties":{"tag_ids":{"type":"array","items":{"type":"string","format":"uuid"},"maxItems":100,"uniqueItems":true},"expected_tag_ids":{"type":"array","items":{"type":"string","format":"uuid"},"maxItems":100,"uniqueItems":true},"mode":{"type":"string","enum":["add","replace"]}}}}}},"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Customers"]}},"/jobs/{id}/tags":{"put":{"operationId":"update_jobs_tags","summary":"Update direct tag assignments","description":"Requires write:tag_assignments. Supply complete current direct tag IDs as expected_tag_ids. Add preserves existing tags; replace may remove them. Contact changes and explicit shared-to-primary-contact propagation require unrestricted company access. Only both-scope tags propagate, additively; related job tags never become direct safety flags implicitly. The update, its audit record and the receipt are saved together. 409 requires reviewing latest state.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["tag_ids","expected_tag_ids","mode"],"properties":{"tag_ids":{"type":"array","items":{"type":"string","format":"uuid"},"maxItems":100,"uniqueItems":true},"expected_tag_ids":{"type":"array","items":{"type":"string","format":"uuid"},"maxItems":100,"uniqueItems":true},"mode":{"type":"string","enum":["add","replace"]},"apply_shared_to_primary_contact":{"type":"boolean","default":false}}}}}},"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Jobs"]}},"/contacts/{id}/notes":{"post":{"operationId":"add_contacts_note","summary":"Append a note","description":"Requires write:notes. Explicit new permission; existing grants are unchanged. Target, exact bytes and Idempotency-Key are bound to the stored receipt. No consent or company overrides.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["content"],"properties":{"content":{"type":"string","minLength":1,"maxLength":10000},"visibility":{"type":"string","enum":["internal","customer"],"default":"internal"}}}}}},"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Customers"]}},"/jobs/{id}/notes":{"post":{"operationId":"add_jobs_note","summary":"Append a note","description":"Requires write:notes. Explicit new permission; existing grants are unchanged. Target, exact bytes and Idempotency-Key are bound to the stored receipt. No consent or company overrides.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["content"],"properties":{"content":{"type":"string","minLength":1,"maxLength":10000},"visibility":{"type":"string","enum":["internal","customer"],"default":"internal"}}}}}},"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Jobs"]}},"/quotes/{id}/invoice":{"post":{"operationId":"create_invoice_from_accepted_quote","summary":"Convert an accepted quote to an invoice","description":"Requires write:invoices. Explicit new permission; existing grants are unchanged. Target, exact bytes and Idempotency-Key are bound to the stored receipt. No consent or company overrides.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"maxProperties":0}}}},"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Quotes"]}},"/tasks/{id}/instructions":{"get":{"operationId":"get_task_instructions","summary":"Review current authored task instructions","description":"Requires read:tasks AND read:activity and unrestricted company access. Returns id, company_id, title, notes, updated_at, status_id and can_edit. Finalized and crew-linked work is not editable here. No query parameters.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Tasks & Visits"]}},"/operations/task_instructions/{key}":{"get":{"operationId":"get_task_instruction_operation","summary":"Read this connection’s committed task instruction outcome","description":"Requires write:task_instructions and unrestricted company access. Missing is not proof an in-flight edit failed. No notification is implied.","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Receipts"]}},"/tasks/{id}/completion-notes":{"get":{"operationId":"get_task_completion_notes","summary":"Review completed-task notes","description":"Requires read:tasks AND read:activity. Returns id, company_id, status_id, updated_at and completed_notes Completed tasks only; no raw metadata or query parameters.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Tasks & Visits"]},"patch":{"operationId":"correct_task_completion_notes","summary":"Correct reviewed completed-task notes","description":"Requires separate write:task_note_corrections; existing task creation/note permissions do not authorize corrections. JSON limit 128 KiB. Exact last-read notes and updated_at prevent stale writes; empty replacement explicitly clears text. The correction, its audit record and the receipt are saved together. No status, technician, completion time/revision/snapshot, signature, inventory, approval, billing, commission or dispatch changes; no customer notification. Corrected text is not proof of operational effects. Exact retries return the original receipt; 409 requires reviewing current state.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["expected_updated_at","expected_notes","notes"],"properties":{"expected_updated_at":{"type":"string","format":"date-time","maxLength":64},"expected_notes":{"type":"string","maxLength":20000},"notes":{"type":"string","maxLength":20000}}}}}},"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Tasks & Visits"]}},"/quotes/{id}/revise":{"post":{"operationId":"revise_quote","summary":"Supersede a quote with an unsent draft","description":"Requires write:quote_revisions and unrestricted company access. The revision keeps the customer and proposal content, resets acceptance on the new draft, and may void only unpaid invoices; paid history remains intact. No price overrides, acceptance, sending or payments. Last-read updated_at is required. The change, its audit record and the receipt are saved together; 409 means review the current state first.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["expected_updated_at"],"properties":{"expected_updated_at":{"type":"string","format":"date-time","maxLength":64}}}}}},"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Quotes"]}},"/contacts/{id}/send-portal-link":{"post":{"operationId":"send_portal_link","summary":"Send a customer their portal link","description":"Requires separately approved write:portal_link_sends and access to the customer’s company. Supply the customer’s reviewed updated_at and one or both channels. Sends your company’s customer portal address to the customer’s saved email and/or phone using your portal link email and text templates; the customer signs in with a one-time code, so the link grants no access by itself. The customer’s company needs a customer portal and the customer’s portal access must be on. The customer must allow that channel; unsubscribes and blocks apply. Every check runs before anything is sent; nothing is sent if any selected channel is unavailable. state: submitted (every channel confirmed), partial (some confirmed), needs_reconciliation (no confirmation; review the customer’s messages before sending again). Exact retries return the original result and never send twice.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["expected_updated_at","channels"],"properties":{"expected_updated_at":{"type":"string","format":"date-time","maxLength":64},"channels":{"type":"array","minItems":1,"maxItems":2,"uniqueItems":true,"items":{"type":"string","enum":["email","sms"]}}}}}}},"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Customers"]}},"/operations/portal_link_send/{key}":{"get":{"operationId":"get_portal_link_send_operation","summary":"Read this connection’s portal link send outcome","description":"Requires write:portal_link_sends. Returns the operation state and the sent email/text references, never message content. Missing does not prove an in-flight request failed.","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Receipts"]}},"/agreements/{id}/send":{"post":{"operationId":"send_agreement_for_signature","summary":"Send a service agreement for signature","description":"Requires separately approved write:agreement_sends and access to the agreement’s company. Only agreements awaiting a signature (pending and unsigned) are eligible. Supply the agreement’s reviewed updated_at and one or both channels. The signing link goes to the agreement’s customer at their saved email and/or phone only. Each accepted request issues a fresh signing link valid for 30 days and retires any earlier link, the same as resending from the office; the agreement’s updated_at changes as a result. The customer must allow that channel; unsubscribes and blocks apply. Every check runs before anything is sent; nothing is sent and no link is replaced if any selected channel is unavailable. state: submitted (every channel confirmed), partial (some confirmed), needs_reconciliation (no confirmation; review the customer’s messages before sending again, since only the newest link works). Never signs the agreement or changes its terms, price or dates. Exact retries return the original result and never send twice.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["expected_updated_at","channels"],"properties":{"expected_updated_at":{"type":"string","format":"date-time","maxLength":64},"channels":{"type":"array","minItems":1,"maxItems":2,"uniqueItems":true,"items":{"type":"string","enum":["email","sms"]}}}}}}},"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Agreements"]}},"/operations/agreement_send/{key}":{"get":{"operationId":"get_agreement_send_operation","summary":"Read this connection’s agreement send outcome","description":"Requires write:agreement_sends. Returns the operation state and the sent email/text references, never message content or the signing link. Missing does not prove an in-flight request failed.","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Receipts"]}},"/payments/{id}/send-receipt":{"post":{"operationId":"send_payment_receipt","summary":"Send a payment receipt to its customer","description":"Requires separately approved write:receipt_sends and access to the payment’s company. Only succeeded payments have receipts. Supply the reviewed updated_at and one or both channels. The receipt goes to the payment’s customer at their saved email and/or phone only, using your company’s receipt email and text templates with the amount, method, date, the invoices it paid and the customer receipt link. The customer must allow that channel; unsubscribes and blocks apply. Every check runs before anything is sent; nothing is sent if any selected channel is unavailable. A confirmed send adds a Receipt Sent entry to the customer’s conversation history. state: submitted (every channel confirmed), partial (some confirmed), needs_reconciliation (no confirmation; review the customer’s messages before sending again). Never charges, refunds or changes the payment. Exact retries return the original result and never send twice.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["expected_updated_at","channels"],"properties":{"expected_updated_at":{"type":"string","format":"date-time","maxLength":64},"channels":{"type":"array","minItems":1,"maxItems":2,"uniqueItems":true,"items":{"type":"string","enum":["email","sms"]}}}}}}},"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Payments"]}},"/operations/receipt_send/{key}":{"get":{"operationId":"get_receipt_send_operation","summary":"Read this connection’s receipt send outcome","description":"Requires write:receipt_sends. Returns the operation state and the sent email/text references, never message content. Missing does not prove an in-flight request failed.","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Receipts"]}},"/quotes/{id}/send":{"post":{"operationId":"send_quote","summary":"Send a quote to its customer","description":"Requires separately approved write:quote_sends and access to the quote’s company. Only draft or sent quotes. Supply the reviewed updated_at and one or both channels. The quote goes to its billing customer (else its customer, else the job’s primary contact) at their saved email and/or phone only, using your company’s quote email and text templates with the customer quote link. The customer must allow that channel; unsubscribes and blocks apply. Every check runs before anything is sent; nothing is sent if any selected channel is unavailable. When at least one message is confirmed sent, a draft quote becomes Sent and its customer link is enabled. state: submitted (every channel confirmed), partial (some confirmed), needs_reconciliation (no confirmation; review the customer’s messages before sending again). Never accepts the quote, takes payment or changes prices. Exact retries return the original result and never send twice.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["expected_updated_at","channels"],"properties":{"expected_updated_at":{"type":"string","format":"date-time","maxLength":64},"channels":{"type":"array","minItems":1,"maxItems":2,"uniqueItems":true,"items":{"type":"string","enum":["email","sms"]}}}}}}},"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Quotes"]}},"/operations/quote_send/{key}":{"get":{"operationId":"get_quote_send_operation","summary":"Read this connection’s quote send outcome","description":"Requires write:quote_sends. Returns the operation state and the sent email/text references, never message content. Missing does not prove an in-flight request failed.","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Receipts"]}},"/quotes/{id}/accept":{"post":{"operationId":"accept_quote","summary":"Record a customer’s agreement to a quote","description":"Requires separately approved write:quote_acceptances and unrestricted company access. JSON limit 16 KiB. Read the quote first and supply its updated_at. Only unaccepted draft or sent quotes without an invoice are eligible; expired quotes must be revised first. Acceptance works exactly like an office acceptance: the invoice is created from the accepted items, the customer’s open leads are closed as won, the conversation history records the acceptance with your authorization note, and the usual sales commission is created and held. No signature is captured, no payment is taken and neither the customer nor staff is notified. Only accept when the customer has actually agreed. Exact retries with the same Idempotency-Key and body return the original result. 201 returns the quote and invoice ids; 202 needs_reconciliation means the outcome could not be confirmed—review the quote before trying again and never repeat it under a new key.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["expected_updated_at","customer_authorization"],"properties":{"expected_updated_at":{"type":"string","format":"date-time","maxLength":64},"customer_authorization":{"type":"string","minLength":1,"maxLength":1500,"description":"How and when the customer agreed, kept with the quote history."},"accepted_item_indexes":{"type":"array","maxItems":200,"uniqueItems":true,"items":{"type":"integer","minimum":0,"maximum":999},"description":"0-based positions of the optional or recommended line items the customer chose. Required items are always included; when the quote does not allow customer choices every item is included."}}}}}},"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Quotes"]}},"/operations/quote_acceptance/{key}":{"get":{"operationId":"get_quote_acceptance_operation","summary":"Read this connection’s quote acceptance outcome","description":"Requires write:quote_acceptances and unrestricted company access. Returns the operation state and, once committed, the quote and invoice ids. Missing does not prove an in-flight request failed.","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Receipts"]}},"/invoices/{id}/send":{"post":{"operationId":"send_invoice","summary":"Send an invoice to its customer","description":"Requires separately approved write:invoice_sends and access to the invoice’s company. Only draft or sent invoices; paid and void invoices are refused. Supply the reviewed updated_at and one or both channels. The invoice goes to its billed customer (else the job’s primary contact) at their saved email and/or phone only, using your company’s invoice email and text templates with the customer payment link. The customer must allow that channel; unsubscribes and blocks apply. Every check runs before anything is sent; nothing is sent if any selected channel is unavailable. When at least one message is confirmed sent, a draft invoice becomes Sent and its customer link is enabled. state: submitted (every channel confirmed), partial (some confirmed), needs_reconciliation (no confirmation; review the customer’s messages before sending again). Never takes payment, applies credit or changes amounts. Exact retries return the original result and never send twice.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["expected_updated_at","channels"],"properties":{"expected_updated_at":{"type":"string","format":"date-time","maxLength":64},"channels":{"type":"array","minItems":1,"maxItems":2,"uniqueItems":true,"items":{"type":"string","enum":["email","sms"]}}}}}}},"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Invoices"]}},"/operations/invoice_send/{key}":{"get":{"operationId":"get_invoice_send_operation","summary":"Read this connection’s invoice send outcome","description":"Requires write:invoice_sends. Returns the operation state and the sent email/text references, never message content. Missing does not prove an in-flight request failed.","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Receipts"]}},"/quotes/{id}/requote":{"post":{"operationId":"replace_unpaid_quote","summary":"Decline and replace a reviewed unpaid quote with an unsent draft","description":"Separate permission and unrestricted company access required. The replacement keeps the quote content and records the decline reason; any invoice with money received prevents replacement. May void unpaid invoices. No corrected items, price overrides, acceptance, sending, charging or notification. Draft edits are a separate workflow. An audit record and receipt are saved with the change; retry with the same request key to recover an uncertain outcome.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["expected_updated_at","reason"],"properties":{"expected_updated_at":{"type":"string","format":"date-time","maxLength":64},"reason":{"type":"string","minLength":1,"maxLength":500}}}}}},"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Quotes"]}},"/subscriptions/{id}/pause":{"post":{"operationId":"pause_recurring_plan","summary":"pause a recurring plan","description":"Requires write:subscription_controls and unrestricted company access. ID identifies the subscription job. Uses the same pause/resume as the office, including related plans. Does not cancel/recreate visits, change financial history, clear separate billing_paused flags, collect money, or notify customers. Cancelled/past-due plans are not eligible. Pause accepts a required reason and optional future resume date. Supply the last-read updated_at. An audit record and receipt are saved with the change.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["expected_updated_at","reason"],"properties":{"expected_updated_at":{"type":"string","format":"date-time","maxLength":64},"reason":{"type":"string","minLength":1,"maxLength":1500},"resume_date":{"type":"string","format":"date"}}}}}},"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Subscriptions"]}},"/subscriptions/{id}/resume":{"post":{"operationId":"resume_recurring_plan","summary":"resume a recurring plan","description":"Requires write:subscription_controls and unrestricted company access. ID identifies the subscription job. Uses the same pause/resume as the office, including related plans. Does not cancel/recreate visits, change financial history, clear separate billing_paused flags, collect money, or notify customers. Cancelled/past-due plans are not eligible. Pause accepts a required reason and optional future resume date. Supply the last-read updated_at. An audit record and receipt are saved with the change.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["expected_updated_at"],"properties":{"expected_updated_at":{"type":"string","format":"date-time","maxLength":64}}}}}},"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Subscriptions"]}},"/contacts/{id}/merge":{"post":{"operationId":"merge_customers","summary":"Merge reviewed duplicate customers","description":"Requires write:contact_merges and unrestricted company access. Primary id and every duplicate require last-read updated_at. Only same-company duplicates are eligible. Merging DELETES the duplicate customer records, moves linked history and credits and retains communication blocks. Explicit review reason required. No new consent, payment or notification. The merge, its audit record and the receipt are saved together; an identical retry returns the original result.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["expected_updated_at","duplicates","reason"],"properties":{"expected_updated_at":{"type":"string","format":"date-time","maxLength":64},"reason":{"type":"string","minLength":1,"maxLength":1500},"duplicates":{"type":"array","minItems":1,"maxItems":100,"items":{"type":"object","additionalProperties":false,"required":["id","expected_updated_at"],"properties":{"id":{"type":"string","format":"uuid"},"expected_updated_at":{"type":"string","format":"date-time","maxLength":64}}}}}}}}},"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Customers"]}},"/jobs/{id}/phase":{"post":{"operationId":"change_job_phase","summary":"Move a job between active work phases","description":"Requires separately approved write:job_phases and unrestricted company access. Read the job first and supply its updated_at; the current phase must differ. Active phases (initial_inspection, trapping, exclusion, monitoring, warranty) change only the phase plus a timeline entry. Completing, cancelling and reopening (a completed or cancelled job may only return to initial_inspection) additionally require write:job_closeouts and a reason, and work exactly as they do in the office: cancelling cancels open visits, denies unpaid commissions and marks linked leads lost, and is refused for purchased, deposited or invoiced work; completing enforces open-visit and Work Signoff rules and releases held commissions only when the job is paid; reopening restores what cancellation changed. All of these changes, the timeline entry, an audit record and the receipt are saved together; route clean-up and commission notices follow once afterwards. No invoice is created and no customer survey or notification is sent. 409 means the record changed or closeout requirements are unmet.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["expected_updated_at","phase"],"properties":{"expected_updated_at":{"type":"string","format":"date-time","maxLength":64},"phase":{"type":"string","enum":["initial_inspection","trapping","exclusion","monitoring","warranty","completed","cancelled"]},"reason":{"type":"string","minLength":1,"maxLength":1500}}}}}},"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Jobs"]}},"/tasks/{id}/status":{"post":{"operationId":"change_task_status","summary":"Unassign, fail or cancel an open task","description":"Requires separately approved write:task_statuses and unrestricted company access. Read the task first and supply its updated_at plus a reason. Only open tasks (unassigned, assigned, on the way, arrived or in progress) are eligible; crew visits follow their parent task, and Pending Approval work uses the approve and reject endpoints. unassigned returns the task to the unassigned pool and clears its technician and route position; failed keeps the technician on record; cancelled removes the assignment. Failing or cancelling a task does the same to its open crew visits but never discards submitted crew work. The status change, crew visits, assignment history, timeline entry, audit record and receipt are saved together, exactly as in the office; route clean-up follows once afterwards. This endpoint never completes work, sets field progress (on the way, arrived, in progress) or notifies customers or technicians. 409 means the task changed or is not eligible.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["expected_updated_at","status","reason"],"properties":{"expected_updated_at":{"type":"string","format":"date-time","maxLength":64},"status":{"type":"string","enum":["unassigned","failed","cancelled"]},"reason":{"type":"string","minLength":1,"maxLength":1500}}}}}},"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Tasks & Visits"]}},"/tasks/{id}/assign":{"post":{"operationId":"assign_task","summary":"Assign or reassign a task to a field technician","description":"Requires separately approved write:task_assignments and access to the task’s company. JSON limit 8 KiB. Read the task first and supply its updated_at. Only unassigned or assigned tasks that have not started are eligible; crew visits follow their parent task, Pending Approval and finished work are refused, and a task pinned on its current route must be unpinned by a dispatcher first. The technician must be an active field technician who can work the task’s company and dispatch market, and must not already be crew on it. Assigning works like a dispatcher’s reassignment: the task moves off any previous route, its assignment history and a permanent revision record are updated, and the change, an audit record and the receipt are saved together. Afterwards the task is placed on the technician’s route (route_placement: placed, or deferred when the next route optimization will place it; tasks for a later day stay assigned without a route position). Shift capacity is not checked, so a route can run past the technician’s hours; the automatic shift guard may then move lower-priority work. The technician gets the usual batched new-stop notice unless notify_technician is false. Customers are never notified. Exact retries with the same Idempotency-Key and body return the original result; 409 means the task changed or is not eligible.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["expected_updated_at","technician_user_id"],"properties":{"expected_updated_at":{"type":"string","format":"date-time","maxLength":64},"technician_user_id":{"type":"string","format":"uuid","description":"Employee id of an active field technician (see /employees)."},"reason":{"type":"string","minLength":1,"maxLength":1500},"notify_technician":{"type":"boolean","default":true}}}}}},"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Tasks & Visits"]}},"/tasks/{id}/schedule":{"post":{"operationId":"schedule_task","summary":"Schedule, reschedule or unschedule a task","description":"Requires separately approved write:task_schedules and access to the task’s company. JSON limit 8 KiB. Read the task first and supply its updated_at. Only unassigned or assigned tasks that have not started are eligible; crew visits follow their parent task, and Pending Approval, finished and multi-day project work is refused. schedule: window sets start_at and end_at (the window must not already be over and can span at most 14 days); all_day sets date and uses the company’s business hours in its own time zone; unscheduled clears the schedule. An all-day customer appointment may add arrive_by, the latest time the customer is available (for example 17:30 when they are home until 5:30); it must be after the company opens and not already passed, and every all_day request restates it, so omitting it clears an earlier one. Routing and automatic dispatch then aim to arrive by that time. A customer appointment keeps start_at to end_at as its arrival window, which can be at most 6 hours; use all_day, or customer_appointment false for a flexible stop, for anything longer. Property access hours move with the visit, a capture pickup deadline is never changed, and open crew visits get the same schedule. The change, permanent revision records, an audit record and the receipt are saved together. Afterwards each assigned stop is re-placed on its technician’s route (route_placement: placed, later_day when the visit is on a later day, deferred when the next route optimization will place it, or not_assigned). Technician availability and shift capacity are not checked, the same as an office edit. Neither customers nor technicians are notified. Exact retries with the same Idempotency-Key and body return the original result; 409 means the task changed or is not eligible.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["expected_updated_at","schedule"],"properties":{"expected_updated_at":{"type":"string","format":"date-time","maxLength":64},"schedule":{"type":"string","enum":["window","all_day","unscheduled"]},"start_at":{"type":"string","format":"date-time","maxLength":64,"description":"ISO 8601 with a time zone offset or Z."},"end_at":{"type":"string","format":"date-time","maxLength":64,"description":"ISO 8601 with a time zone offset or Z."},"date":{"type":"string","format":"date","description":"Calendar day in the company’s own time zone (all_day only)."},"arrive_by":{"type":"string","pattern":"^([01]\\d|2[0-3]):[0-5]\\d$","description":"Latest time the customer is available that day, HH:MM in the company’s own time zone (all_day customer appointments only). Omit to clear it."},"customer_appointment":{"type":"boolean","description":"Defaults to the task’s current setting; unscheduled tasks are never customer appointments."},"reason":{"type":"string","minLength":1,"maxLength":1500}}}}}},"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Tasks & Visits"]}},"/jobs/{id}/contacts":{"get":{"operationId":"get_job_contacts","summary":"Complete linked contact review snapshot","description":"Requires read:jobs AND read:contacts. Returns job id, updated_at, contacts (contact_id/is_primary/role) and complete=true. Company scoped; sets exceeding 100 fail explicitly. No person details. No query parameters.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Jobs"]},"put":{"operationId":"replace_job_contacts","summary":"Replace the full linked job contact set","description":"Requires write:job_contacts and unrestricted company access. First read GET on this path; provide the complete reviewed membership plus job updated_at. Desired nonempty set requires exactly one primary; empty explicitly removes all linked contacts. Linked properties and open visits are updated to match. No booking, phase, payment or notification. The change, its audit record and the receipt are saved together; 409 means review again.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["expected_updated_at","expected_contacts","contacts"],"properties":{"expected_updated_at":{"type":"string","format":"date-time","maxLength":64},"contacts":{"type":"array","maxItems":100,"items":{"type":"object","additionalProperties":false,"required":["contact_id","is_primary","role"],"properties":{"contact_id":{"type":"string","format":"uuid"},"is_primary":{"type":"boolean"},"role":{"type":"string","minLength":1,"maxLength":80}}}},"expected_contacts":{"type":"array","maxItems":100,"items":{"type":"object","additionalProperties":false,"required":["contact_id","is_primary","role"],"properties":{"contact_id":{"type":"string","format":"uuid"},"is_primary":{"type":"boolean"},"role":{"type":"string","nullable":true,"maxLength":80}}}}}}}}},"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Jobs"]}},"/operations/task/{key}":{"get":{"operationId":"get_task_operation","summary":"Read this connection's task outcome","description":"Requires write:tasks. No key takeover or automated replay. A missing receipt does not prove an in-flight operation failed.","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Receipts"]}},"/operations/quote/{key}":{"get":{"operationId":"get_quote_operation","summary":"Read this connection's quote outcome","description":"Requires write:quotes. No key takeover or automated replay. A missing receipt does not prove an in-flight operation failed.","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Receipts"]}},"/appointments":{"post":{"operationId":"create_appointment","summary":"Create an appointment","description":"Requires write:appointments and unrestricted company access. Uses the same workflow as the office and is attempted exactly once per request key. Tasks are unassigned/unscheduled work on an existing job; quotes are unsent one-time live-catalog drafts with exact variants, not accepted orders. Appointments reuse the active company widget and its booking/payment/availability rules at an existing property; deposit and recurring plans use customer-facing workflows. Provider and uncertain writes are never automatically repeated. Optional source_lead_id and expected_lead_updated_at must appear together and additionally require write:lead_conversions. Only an open, unlinked lead at its exact existing customer/company and saved property is eligible. The booking, lead conversion, audit record and receipt (lead_converted=true) are saved together. Booking also closes other open leads for the same customer and company. No payment or new communication consent is requested. Conflicts/unproven outcomes require the original operation receipt and staff review, not another request identity.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["widget_id","contact_id","property_id","service_id","requested_time"],"properties":{"widget_id":{"type":"string","format":"uuid"},"contact_id":{"type":"string","format":"uuid"},"property_id":{"type":"string","format":"uuid"},"service_id":{"type":"string","format":"uuid"},"variant_id":{"type":"string","format":"uuid"},"requested_time":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:00$","description":"Company-local time, not UTC; confirm the appointment time returned in the response"},"booking_hold_id":{"type":"string","format":"uuid"},"source_lead_id":{"type":"string","format":"uuid"},"expected_lead_updated_at":{"type":"string","format":"date-time","maxLength":64}},"oneOf":[{"not":{"anyOf":[{"required":["source_lead_id"]},{"required":["expected_lead_updated_at"]}]}},{"required":["source_lead_id","expected_lead_updated_at"]}]}}}},"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Appointments"]}},"/operations/appointment/{key}":{"get":{"operationId":"get_appointment_operation","summary":"Read this connection's appointment outcome","description":"Requires write:appointments. No key takeover or automated replay. A missing receipt does not prove an in-flight operation failed. Lead-conversion results additionally require write:lead_conversions; lead_converted=true and lead_id identify the committed conversion.","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Receipts"]}},"/tasks/{id}/reject":{"post":{"operationId":"reject_task_completion","summary":"Send reviewed Pending Approval work back for redo, exactly like a supervisor rejection in the office. Resets the submission and denies pending automatic commissions, keeping the audit history. Does not submit completion, reinsert a route stop or send a technician notification.","description":"Requires write:task_rejections and unrestricted company access. Send reviewed Pending Approval work back for redo, exactly like a supervisor rejection in the office. Resets the submission and denies pending automatic commissions, keeping the audit history. Does not submit completion, reinsert a route stop or send a technician notification. JSON limit 64 KiB. The reviewed values, an audit record and the receipt are saved with the change. A 409 means reviewed state or retry identity changed; review before a new request. Never automatically replay an uncertain result under a new identity.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["expected_updated_at","rejection_reason"],"properties":{"expected_updated_at":{"type":"string","format":"date-time","maxLength":64},"rejection_reason":{"type":"string","minLength":1,"maxLength":2000}}}}}},"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Tasks & Visits"]}},"/operations/task_reject/{key}":{"get":{"operationId":"get_task_reject_operation","summary":"Read a connection-owned committed outcome","description":"Requires write:task_rejections and unrestricted company access. Returns only this connection’s receipt. Approval receipts summarize follow-up work status only. Missing is not proof an in-flight request failed; uncertain notifications are never automatically resent.","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Receipts"]}},"/tasks/{id}/approve":{"post":{"operationId":"approve_task","summary":"Approve reviewed Pending Approval work, exactly like a supervisor approval in the office, including signoff checks. Keeps the technician’s completion time. Commissions, follow-ups and notifications run afterwards; a successful response does not confirm their delivery.","description":"Requires write:task_approvals and unrestricted company access. Approve reviewed Pending Approval work, exactly like a supervisor approval in the office, including signoff checks. Keeps the technician’s completion time. Commissions, follow-ups and notifications run afterwards; a successful response does not confirm their delivery. JSON limit 64 KiB. The reviewed values, an audit record and the receipt are saved with the change. A 409 means reviewed state or retry identity changed; review before a new request. Never automatically replay an uncertain result under a new identity.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["expected_updated_at"],"properties":{"expected_updated_at":{"type":"string","format":"date-time","maxLength":64}}}}}},"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Tasks & Visits"]}},"/operations/task_approve/{key}":{"get":{"operationId":"get_task_approve_operation","summary":"Read a connection-owned committed outcome","description":"Requires write:task_approvals and unrestricted company access. Returns only this connection’s receipt. Approval receipts summarize follow-up work status only. Missing is not proof an in-flight request failed; uncertain notifications are never automatically resent.","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Receipts"]}},"/operations/payment_allocate/{key}":{"get":{"operationId":"get_payment_allocate_operation","summary":"Read a connection-owned committed outcome","description":"Requires write:payment_allocations and unrestricted company access. Returns only this connection’s receipt. Approval receipts summarize follow-up work status only. Missing is not proof an in-flight request failed; uncertain notifications are never automatically resent.","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Receipts"]}},"/leads/{id}/convert":{"post":{"operationId":"convert_lead_to_existing_job","summary":"Mark an open lead won by linking an EXISTING non-cancelled same-company job that already belongs to that exact customer. Review both updated_at values first. Does not create a job, appointment, quote, payment or notification; never matches identities by name or address or moves a lead to another customer.","description":"Requires write:lead_conversions and unrestricted company access. Mark an open lead won by linking an EXISTING non-cancelled same-company job that already belongs to that exact customer. Review both updated_at values first. Does not create a job, appointment, quote, payment or notification; never matches identities by name or address or moves a lead to another customer. JSON limit 64 KiB. The reviewed values, an audit record and the receipt are saved with the change. A 409 means reviewed state or retry identity changed; review before a new request. Never automatically replay an uncertain result under a new identity.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["expected_updated_at","job_id","expected_job_updated_at"],"properties":{"expected_updated_at":{"type":"string","format":"date-time","maxLength":64},"job_id":{"type":"string","format":"uuid"},"expected_job_updated_at":{"type":"string","format":"date-time","maxLength":64}}}}}},"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Leads"]}},"/operations/lead_convert/{key}":{"get":{"operationId":"get_lead_convert_operation","summary":"Read a connection-owned committed outcome","description":"Requires write:lead_conversions and unrestricted company access. Returns only this connection’s receipt. Approval receipts summarize follow-up work status only. Missing is not proof an in-flight request failed; uncertain notifications are never automatically resent.","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Receipts"]}},"/leads/{id}/status-options":{"get":{"operationId":"get_lead_status_options","summary":"Review current configured lead stages and loss reasons","description":"Requires read:leads and exact company access. Returns id, company_id, status, updated_at, can_set_status/can_mark_lost/can_reopen, active nonterminal statuses, loss_status, managed lost_reasons, configuration sources, conversion=existing_job_only and policy_revision. Company status overrides fall back to organization then built-in defaults; loss reasons use organization/platform/code defaults plus Other. No notes or query parameters.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Leads"]}},"/leads/{id}/status":{"post":{"operationId":"change_lead_status","summary":"Change a reviewed lead stage, record a loss or explicitly reopen","description":"Requires separate write:lead_statuses and exact company access. JSON limit 32 KiB. First review status-options; supply expected_updated_at and expected_policy_revision. set_status uses an active configured nonterminal name. mark_lost requires a configured reason; Other requires other_reason, forbidden otherwise. reopen requires a lost lead, an active nonterminal status and a reason, preserving previous loss evidence in audit. Won/converted, job-linked or accepted-quote leads are refused. No booking, quote, payment, consent or customer notification. Mutation, actor audit and exact-byte receipt commit together. 409 requires fresh review, never automatic replay under a new identity.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"oneOf":[{"type":"object","additionalProperties":false,"required":["expected_updated_at","expected_policy_revision","operation","status"],"properties":{"expected_updated_at":{"type":"string","format":"date-time","maxLength":64},"expected_policy_revision":{"type":"string","pattern":"^[0-9a-f]{64}$"},"operation":{"type":"string","enum":["set_status"]},"status":{"type":"string","minLength":1,"maxLength":200}}},{"type":"object","additionalProperties":false,"required":["expected_updated_at","expected_policy_revision","operation","lost_reason"],"properties":{"expected_updated_at":{"type":"string","format":"date-time","maxLength":64},"expected_policy_revision":{"type":"string","pattern":"^[0-9a-f]{64}$"},"operation":{"type":"string","enum":["mark_lost"]},"lost_reason":{"type":"string","minLength":1,"maxLength":500},"other_reason":{"type":"string","minLength":1,"maxLength":2000}},"description":"Other requires other_reason; other_reason is forbidden for a configured reason."},{"type":"object","additionalProperties":false,"required":["expected_updated_at","expected_policy_revision","operation","status","reason"],"properties":{"expected_updated_at":{"type":"string","format":"date-time","maxLength":64},"expected_policy_revision":{"type":"string","pattern":"^[0-9a-f]{64}$"},"operation":{"type":"string","enum":["reopen"]},"status":{"type":"string","minLength":1,"maxLength":200},"reason":{"type":"string","minLength":1,"maxLength":2000}}}]}}}},"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Leads"]}},"/operations/lead_status/{key}":{"get":{"operationId":"get_lead_status_operation","summary":"Read this connection’s committed lead status outcome","description":"Requires write:lead_statuses and receipt company access. Missing is not proof an in-flight request failed. Reuse only the original identity and exact bytes; no booking or customer notification is implied.","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Receipts"]}},"/quotes/{id}/decline-options":{"get":{"operationId":"get_quote_decline_options","summary":"Review eligibility and managed quote decline reasons","description":"Requires read:quotes and exact company access. Returns id, company_id, status, can_decline, quote_revision, policy_revision, reasons and reason_source. Reasons use organization/platform/code defaults plus Other. Quote review uses a revision hash, not an updated_at timestamp. No notes, financial details, signatures or query parameters.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Quotes"]}},"/quotes/{id}/decline":{"post":{"operationId":"decline_quote","summary":"Decline an unaccepted reviewed quote","description":"Requires separately approved write:quote_declines and unrestricted company access. First read decline-options and supply expected_quote_revision and expected_policy_revision. JSON limit 32 KiB. Only draft/sent quotes without acceptance, signature or any invoice are eligible. Other requires other_reason, forbidden otherwise. The decline, conversation history, an audit record and the receipt are saved together. No change to scope, invoices, payments, scheduled work or customer notification. Conflicts require fresh review; never automatically repeat an uncertain operation under a new key.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["expected_quote_revision","expected_policy_revision","reason"],"properties":{"expected_quote_revision":{"type":"string","pattern":"^[0-9a-f]{64}$"},"expected_policy_revision":{"type":"string","pattern":"^[0-9a-f]{64}$"},"reason":{"type":"string","minLength":1,"maxLength":500},"other_reason":{"type":"string","minLength":1,"maxLength":2000}},"description":"Read decline-options first. Other requires other_reason; other_reason is forbidden for configured reasons."}}}},"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Quotes"]}},"/operations/quote_decline/{key}":{"get":{"operationId":"get_quote_decline_operation","summary":"Read this connection’s committed decline receipt","description":"Requires write:quote_declines and unrestricted company access. Missing does not prove an in-flight request failed. No customer notification is implied.","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"responses":{"200":{"description":"Authorized result or exact replay"},"201":{"description":"Durable record committed"},"202":{"description":"Still in progress or needs review (attempting / needs_reconciliation). This is not success; do not resend under a new request key."},"400":{"description":"Invalid request"},"403":{"description":"Explicit permission or tenant/company access unavailable"},"404":{"description":"Record not found within approved access"},"409":{"description":"Request identity conflicts with prior target or exact bytes"},"422":{"description":"Invalid input or workflow state"},"503":{"description":"Outcome unavailable; never assume success"}},"tags":["Receipts"]}},"/invoices/{id}/void":{"post":{"operationId":"invoice_void","summary":"Void an unpaid invoice","description":"Requires write:invoice_voids. Voids an invoice with no money applied and records the reason on the customer timeline. Paid or partly paid invoices are refused; reverse or reallocate payments first. Retrying with the same Idempotency-Key and identical content returns the original result without repeating the change. Recover a lost response with GET /operations/invoice_void/{key}.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["reason"],"properties":{"reason":{"type":"string","minLength":1,"maxLength":1000}}}}}},"responses":{"200":{"description":"Committed, or the original result of an identical retry"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Invoices"]}},"/credits/{id}/void":{"post":{"operationId":"credit_void","summary":"Void an active credit","description":"Requires write:credits. Voids an active credit memo and records the reason. Retrying with the same Idempotency-Key and identical content returns the original result without repeating the change. Recover a lost response with GET /operations/credit_void/{key}.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["expected_updated_at","reason"],"properties":{"expected_updated_at":{"type":"string","format":"date-time","description":"The updated_at you last read. A newer value is refused with 409."},"reason":{"type":"string","minLength":1,"maxLength":1000}}}}}},"responses":{"200":{"description":"Committed, or the original result of an identical retry"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Credits"]}},"/subscriptions/{id}/skip-next-visit":{"post":{"operationId":"plan_skip","summary":"Skip or un-skip the next plan visit","description":"Requires write:plan_changes. Sets whether the next recurring visit is skipped. Billing continues on its own schedule. Retrying with the same Idempotency-Key and identical content returns the original result without repeating the change. Recover a lost response with GET /operations/plan_skip/{key}.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["expected_updated_at","skip"],"properties":{"expected_updated_at":{"type":"string","format":"date-time","description":"The updated_at you last read. A newer value is refused with 409."},"skip":{"type":"boolean"}}}}}},"responses":{"200":{"description":"Committed, or the original result of an identical retry"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Subscriptions"]}},"/subscriptions/{id}/cancel":{"post":{"operationId":"plan_cancel","summary":"Cancel a recurring plan","description":"Requires write:plan_changes. Cancels the plan exactly as the office Cancel action does: open visits are cancelled and removed from routes, plan quotes and leads close, the customer is emailed, and an early termination fee is invoiced when the agreement has one and early_termination_fee is charge. A prorated credit is issued when your billing settings use proration. Response 502 means the cancellation did not finish: read the plan and send a new request if it is still active. Retrying with the same Idempotency-Key and identical content returns the original result without repeating the change. Recover a lost response with GET /operations/plan_cancel/{key}.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["expected_updated_at","reason","early_termination_fee"],"properties":{"expected_updated_at":{"type":"string","format":"date-time","description":"The updated_at you last read. A newer value is refused with 409."},"reason":{"type":"string","minLength":1,"maxLength":1500},"early_termination_fee":{"type":"string","enum":["charge","waive"]}}}}}},"responses":{"200":{"description":"Committed, or the original result of an identical retry"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Subscriptions"]}},"/cameras/{id}/assign":{"post":{"operationId":"camera_assign","summary":"Assign a camera to a job","description":"Requires write:cameras. Assigns the camera to an open job at the job property's mapped location, ends its previous assignment and takes it off any truck, exactly as the office does. Archived cameras are refused. Retrying with the same Idempotency-Key and identical content returns the original result without repeating the change. Recover a lost response with GET /operations/camera_assign/{key}.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["expected_updated_at","job_id"],"properties":{"expected_updated_at":{"type":"string","format":"date-time","description":"The updated_at you last read. A newer value is refused with 409."},"job_id":{"type":"string","format":"uuid"}}}}}},"responses":{"200":{"description":"Committed, or the original result of an identical retry"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Cameras"]}},"/cameras/{id}/archive":{"post":{"operationId":"camera_archive","summary":"Archive a camera","description":"Requires write:cameras. Archives the camera, ending its job assignment, trap pairings and truck record so it is no longer treated as deployed. Retrying with the same Idempotency-Key and identical content returns the original result without repeating the change. Recover a lost response with GET /operations/camera_archive/{key}.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["expected_updated_at","reason"],"properties":{"expected_updated_at":{"type":"string","format":"date-time","description":"The updated_at you last read. A newer value is refused with 409."},"reason":{"type":"string","minLength":1,"maxLength":1000}}}}}},"responses":{"200":{"description":"Committed, or the original result of an identical retry"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Cameras"]}},"/tasks/{id}/crew":{"post":{"operationId":"crew_add","summary":"Add a crew member to a visit","description":"Requires write:task_crews. Adds an active field technician as crew on an open primary visit, as the office Add Crew action does: they get their own crew visit on their route. Response 502 means the crew change did not finish: read the visit and send a new request if it is still needed. Retrying with the same Idempotency-Key and identical content returns the original result without repeating the change. Recover a lost response with GET /operations/crew_add/{key}.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["expected_updated_at","technician_user_id"],"properties":{"expected_updated_at":{"type":"string","format":"date-time","description":"The updated_at you last read. A newer value is refused with 409."},"technician_user_id":{"type":"string","format":"uuid"}}}}}},"responses":{"200":{"description":"Committed, or the original result of an identical retry"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Tasks & Visits"]}},"/tasks/{id}/crew/remove":{"post":{"operationId":"crew_remove","summary":"Remove a crew member from a visit","description":"Requires write:task_crews. Removes a crew member from an open primary visit and cancels their crew visit. Retrying with the same Idempotency-Key and identical content returns the original result without repeating the change. Recover a lost response with GET /operations/crew_remove/{key}.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["expected_updated_at","technician_user_id"],"properties":{"expected_updated_at":{"type":"string","format":"date-time","description":"The updated_at you last read. A newer value is refused with 409."},"technician_user_id":{"type":"string","format":"uuid"}}}}}},"responses":{"200":{"description":"Committed, or the original result of an identical retry"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Tasks & Visits"]}},"/corporate_accounts/{id}/sites":{"post":{"operationId":"corporate_site_create","summary":"Add a building to a property account","description":"Requires write:corporate_accounts. Adds a building (site) to a property manager account, as the office does. Retrying with the same Idempotency-Key and identical content returns the original result without repeating the change. Recover a lost response with GET /operations/corporate_site_create/{key}.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["name"],"properties":{"name":{"type":"string","minLength":1,"maxLength":200},"address":{"type":"string","maxLength":300,"nullable":true},"notes":{"type":"string","maxLength":2000,"nullable":true}}}}}},"responses":{"200":{"description":"Original result of an identical retry (replayed true)"},"201":{"description":"Committed; data holds the result and replayed is false"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Property Accounts"]}},"/corporate_accounts/{id}/units":{"post":{"operationId":"corporate_unit_create","summary":"Add a unit to a property account","description":"Requires write:corporate_accounts. Adds a unit, optionally in one of the account's buildings. Retrying with the same Idempotency-Key and identical content returns the original result without repeating the change. Recover a lost response with GET /operations/corporate_unit_create/{key}.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["label"],"properties":{"site_id":{"type":"string","format":"uuid","nullable":true},"label":{"type":"string","minLength":1,"maxLength":120},"address":{"type":"string","maxLength":300,"nullable":true},"payer_override":{"type":"string","enum":["account","tenant",""],"description":"Who pays for this unit's work; empty uses the account rules."},"notes":{"type":"string","maxLength":2000,"nullable":true}}}}}},"responses":{"200":{"description":"Original result of an identical retry (replayed true)"},"201":{"description":"Committed; data holds the result and replayed is false"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Property Accounts"]}},"/corporate_units/{id}/tenants":{"post":{"operationId":"corporate_tenant_add","summary":"Move a tenant into a unit","description":"Requires write:corporate_accounts. Records a customer as a current tenant of the unit. Portal access is on unless portal_access is false. Never sends an invitation. Retrying with the same Idempotency-Key and identical content returns the original result without repeating the change. Recover a lost response with GET /operations/corporate_tenant_add/{key}.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["contact_id"],"properties":{"contact_id":{"type":"string","format":"uuid"},"move_in_date":{"type":"string","format":"date"},"portal_access":{"type":"boolean"},"is_primary":{"type":"boolean"}}}}}},"responses":{"200":{"description":"Original result of an identical retry (replayed true)"},"201":{"description":"Committed; data holds the result and replayed is false"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Property Accounts"]}},"/corporate_tenancies/{id}/move-out":{"post":{"operationId":"corporate_tenant_move_out","summary":"Move a tenant out","description":"Requires write:corporate_accounts. Ends the tenancy and the tenant's access to the unit. The former tenant's record is kept for follow-up; their own contact permissions still apply. Retrying with the same Idempotency-Key and identical content returns the original result without repeating the change. Recover a lost response with GET /operations/corporate_tenant_move_out/{key}.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["expected_updated_at","end_reason"],"properties":{"expected_updated_at":{"type":"string","format":"date-time","description":"The updated_at you last read. A newer value is refused with 409."},"end_reason":{"type":"string","enum":["moved_out","access_revoked","transferred","other"]},"move_out_date":{"type":"string","format":"date"},"forwarding_address":{"type":"string","maxLength":300,"nullable":true}}}}}},"responses":{"200":{"description":"Committed, or the original result of an identical retry"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Property Accounts"]}},"/corporate_units/{id}/requests":{"post":{"operationId":"corporate_request_create","summary":"File a service request for a unit","description":"Requires write:corporate_accounts. Files a service request for the unit, as the office does. Who pays is resolved from the account rules. Requests filed this way are approved; the office schedules the work. Retrying with the same Idempotency-Key and identical content returns the original result without repeating the change. Recover a lost response with GET /operations/corporate_request_create/{key}.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["description"],"properties":{"description":{"type":"string","minLength":3,"maxLength":2000},"service_id":{"type":"string","format":"uuid"},"tenant_contact_id":{"type":"string","format":"uuid"},"preferred_date":{"type":"string","format":"date"},"preferred_window":{"type":"string","enum":["morning","afternoon","evening","any"]}}}}}},"responses":{"200":{"description":"Original result of an identical retry (replayed true)"},"201":{"description":"Committed; data holds the result and replayed is false"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Property Accounts"]}},"/corporate_requests/{id}/decision":{"post":{"operationId":"corporate_request_decide","summary":"Approve or decline a waiting request","description":"Requires write:corporate_accounts. Approves or declines a service request that is waiting for approval. Approval does not schedule a visit; the office schedules approved work. Retrying with the same Idempotency-Key and identical content returns the original result without repeating the change. Recover a lost response with GET /operations/corporate_request_decide/{key}.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["expected_updated_at","decision"],"properties":{"expected_updated_at":{"type":"string","format":"date-time","description":"The updated_at you last read. A newer value is refused with 409."},"decision":{"type":"string","enum":["approve","decline"]},"note":{"type":"string","maxLength":1000,"nullable":true}}}}}},"responses":{"200":{"description":"Committed, or the original result of an identical retry"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Property Accounts"]}},"/operations/job_create/{key}":{"get":{"operationId":"get_job_create_receipt","summary":"Recover a committed job create result","description":"Requires write:jobs and the same API key. A missing receipt does not prove an in-flight request failed; retry it with the same key and bytes instead.","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"responses":{"200":{"description":"Original result and committed_at"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"404":{"description":"No committed receipt"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Receipts"]}},"/operations/job_update/{key}":{"get":{"operationId":"get_job_update_receipt","summary":"Recover a committed job update result","description":"Requires write:jobs and the same API key. A missing receipt does not prove an in-flight request failed; retry it with the same key and bytes instead.","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"responses":{"200":{"description":"Original result and committed_at"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"404":{"description":"No committed receipt"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Receipts"]}},"/operations/payment_record/{key}":{"get":{"operationId":"get_payment_record_receipt","summary":"Recover a committed payment record result","description":"Requires write:payments and the same API key. A missing receipt does not prove an in-flight request failed; retry it with the same key and bytes instead.","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"responses":{"200":{"description":"Original result and committed_at"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"404":{"description":"No committed receipt"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Receipts"]}},"/operations/invoice_void/{key}":{"get":{"operationId":"get_invoice_void_receipt","summary":"Recover a committed invoice void result","description":"Requires write:invoice_voids and the same API key. A missing receipt does not prove an in-flight request failed; retry it with the same key and bytes instead.","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"responses":{"200":{"description":"Original result and committed_at"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"404":{"description":"No committed receipt"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Receipts"]}},"/operations/service_create/{key}":{"get":{"operationId":"get_service_create_receipt","summary":"Recover a committed service create result","description":"Requires write:catalog and the same API key. A missing receipt does not prove an in-flight request failed; retry it with the same key and bytes instead.","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"responses":{"200":{"description":"Original result and committed_at"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"404":{"description":"No committed receipt"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Receipts"]}},"/operations/service_update/{key}":{"get":{"operationId":"get_service_update_receipt","summary":"Recover a committed service update result","description":"Requires write:catalog and the same API key. A missing receipt does not prove an in-flight request failed; retry it with the same key and bytes instead.","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"responses":{"200":{"description":"Original result and committed_at"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"404":{"description":"No committed receipt"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Receipts"]}},"/operations/service_delete/{key}":{"get":{"operationId":"get_service_delete_receipt","summary":"Recover a committed service delete result","description":"Requires write:catalog and the same API key. A missing receipt does not prove an in-flight request failed; retry it with the same key and bytes instead.","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"responses":{"200":{"description":"Original result and committed_at"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"404":{"description":"No committed receipt"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Receipts"]}},"/operations/product_create/{key}":{"get":{"operationId":"get_product_create_receipt","summary":"Recover a committed product create result","description":"Requires write:catalog and the same API key. A missing receipt does not prove an in-flight request failed; retry it with the same key and bytes instead.","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"responses":{"200":{"description":"Original result and committed_at"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"404":{"description":"No committed receipt"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Receipts"]}},"/operations/product_update/{key}":{"get":{"operationId":"get_product_update_receipt","summary":"Recover a committed product update result","description":"Requires write:catalog and the same API key. A missing receipt does not prove an in-flight request failed; retry it with the same key and bytes instead.","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"responses":{"200":{"description":"Original result and committed_at"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"404":{"description":"No committed receipt"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Receipts"]}},"/operations/product_delete/{key}":{"get":{"operationId":"get_product_delete_receipt","summary":"Recover a committed product delete result","description":"Requires write:catalog and the same API key. A missing receipt does not prove an in-flight request failed; retry it with the same key and bytes instead.","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"responses":{"200":{"description":"Original result and committed_at"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"404":{"description":"No committed receipt"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Receipts"]}},"/operations/trap_create/{key}":{"get":{"operationId":"get_trap_create_receipt","summary":"Recover a committed trap create result","description":"Requires write:equipment and the same API key. A missing receipt does not prove an in-flight request failed; retry it with the same key and bytes instead.","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"responses":{"200":{"description":"Original result and committed_at"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"404":{"description":"No committed receipt"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Receipts"]}},"/operations/trap_update/{key}":{"get":{"operationId":"get_trap_update_receipt","summary":"Recover a committed trap update result","description":"Requires write:equipment and the same API key. A missing receipt does not prove an in-flight request failed; retry it with the same key and bytes instead.","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"responses":{"200":{"description":"Original result and committed_at"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"404":{"description":"No committed receipt"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Receipts"]}},"/operations/trap_delete/{key}":{"get":{"operationId":"get_trap_delete_receipt","summary":"Recover a committed trap delete result","description":"Requires write:equipment and the same API key. A missing receipt does not prove an in-flight request failed; retry it with the same key and bytes instead.","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"responses":{"200":{"description":"Original result and committed_at"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"404":{"description":"No committed receipt"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Receipts"]}},"/operations/contact_delete/{key}":{"get":{"operationId":"get_contact_delete_receipt","summary":"Recover a committed contact delete result","description":"Requires write:record_deletions and the same API key. A missing receipt does not prove an in-flight request failed; retry it with the same key and bytes instead.","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"responses":{"200":{"description":"Original result and committed_at"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"404":{"description":"No committed receipt"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Receipts"]}},"/operations/property_delete/{key}":{"get":{"operationId":"get_property_delete_receipt","summary":"Recover a committed property delete result","description":"Requires write:record_deletions and the same API key. A missing receipt does not prove an in-flight request failed; retry it with the same key and bytes instead.","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"responses":{"200":{"description":"Original result and committed_at"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"404":{"description":"No committed receipt"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Receipts"]}},"/operations/invoice_create/{key}":{"get":{"operationId":"get_invoice_create_receipt","summary":"Recover a committed invoice create result","description":"Requires write:invoice_edits and the same API key. A missing receipt does not prove an in-flight request failed; retry it with the same key and bytes instead.","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"responses":{"200":{"description":"Original result and committed_at"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"404":{"description":"No committed receipt"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Receipts"]}},"/operations/invoice_update/{key}":{"get":{"operationId":"get_invoice_update_receipt","summary":"Recover a committed invoice update result","description":"Requires write:invoice_edits and the same API key. A missing receipt does not prove an in-flight request failed; retry it with the same key and bytes instead.","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"responses":{"200":{"description":"Original result and committed_at"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"404":{"description":"No committed receipt"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Receipts"]}},"/operations/payment_update/{key}":{"get":{"operationId":"get_payment_update_receipt","summary":"Recover a committed payment update result","description":"Requires write:payment_edits and the same API key. A missing receipt does not prove an in-flight request failed; retry it with the same key and bytes instead.","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"responses":{"200":{"description":"Original result and committed_at"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"404":{"description":"No committed receipt"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Receipts"]}},"/operations/payment_delete/{key}":{"get":{"operationId":"get_payment_delete_receipt","summary":"Recover a committed payment delete result","description":"Requires write:payment_edits and the same API key. A missing receipt does not prove an in-flight request failed; retry it with the same key and bytes instead.","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"responses":{"200":{"description":"Original result and committed_at"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"404":{"description":"No committed receipt"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Receipts"]}},"/operations/credit_create/{key}":{"get":{"operationId":"get_credit_create_receipt","summary":"Recover a committed credit create result","description":"Requires write:credits and the same API key. A missing receipt does not prove an in-flight request failed; retry it with the same key and bytes instead.","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"responses":{"200":{"description":"Original result and committed_at"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"404":{"description":"No committed receipt"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Receipts"]}},"/operations/credit_void/{key}":{"get":{"operationId":"get_credit_void_receipt","summary":"Recover a committed credit void result","description":"Requires write:credits and the same API key. A missing receipt does not prove an in-flight request failed; retry it with the same key and bytes instead.","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"responses":{"200":{"description":"Original result and committed_at"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"404":{"description":"No committed receipt"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Receipts"]}},"/operations/quote_update/{key}":{"get":{"operationId":"get_quote_update_receipt","summary":"Recover a committed quote update result","description":"Requires write:quote_edits and the same API key. A missing receipt does not prove an in-flight request failed; retry it with the same key and bytes instead.","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"responses":{"200":{"description":"Original result and committed_at"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"404":{"description":"No committed receipt"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Receipts"]}},"/operations/plan_skip/{key}":{"get":{"operationId":"get_plan_skip_receipt","summary":"Recover a committed plan skip result","description":"Requires write:plan_changes and the same API key. A missing receipt does not prove an in-flight request failed; retry it with the same key and bytes instead.","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"responses":{"200":{"description":"Original result and committed_at"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"404":{"description":"No committed receipt"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Receipts"]}},"/operations/plan_cancel/{key}":{"get":{"operationId":"get_plan_cancel_receipt","summary":"Recover a committed plan cancel result","description":"Requires write:plan_changes and the same API key. A missing receipt does not prove an in-flight request failed; retry it with the same key and bytes instead.","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"responses":{"200":{"description":"Original result and committed_at"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"404":{"description":"No committed receipt"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Receipts"]}},"/operations/camera_create/{key}":{"get":{"operationId":"get_camera_create_receipt","summary":"Recover a committed camera create result","description":"Requires write:cameras and the same API key. A missing receipt does not prove an in-flight request failed; retry it with the same key and bytes instead.","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"responses":{"200":{"description":"Original result and committed_at"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"404":{"description":"No committed receipt"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Receipts"]}},"/operations/camera_update/{key}":{"get":{"operationId":"get_camera_update_receipt","summary":"Recover a committed camera update result","description":"Requires write:cameras and the same API key. A missing receipt does not prove an in-flight request failed; retry it with the same key and bytes instead.","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"responses":{"200":{"description":"Original result and committed_at"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"404":{"description":"No committed receipt"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Receipts"]}},"/operations/camera_assign/{key}":{"get":{"operationId":"get_camera_assign_receipt","summary":"Recover a committed camera assign result","description":"Requires write:cameras and the same API key. A missing receipt does not prove an in-flight request failed; retry it with the same key and bytes instead.","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"responses":{"200":{"description":"Original result and committed_at"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"404":{"description":"No committed receipt"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Receipts"]}},"/operations/camera_archive/{key}":{"get":{"operationId":"get_camera_archive_receipt","summary":"Recover a committed camera archive result","description":"Requires write:cameras and the same API key. A missing receipt does not prove an in-flight request failed; retry it with the same key and bytes instead.","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"responses":{"200":{"description":"Original result and committed_at"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"404":{"description":"No committed receipt"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Receipts"]}},"/operations/station_create/{key}":{"get":{"operationId":"get_station_create_receipt","summary":"Recover a committed station create result","description":"Requires write:bait_stations and the same API key. A missing receipt does not prove an in-flight request failed; retry it with the same key and bytes instead.","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"responses":{"200":{"description":"Original result and committed_at"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"404":{"description":"No committed receipt"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Receipts"]}},"/operations/station_update/{key}":{"get":{"operationId":"get_station_update_receipt","summary":"Recover a committed station update result","description":"Requires write:bait_stations and the same API key. A missing receipt does not prove an in-flight request failed; retry it with the same key and bytes instead.","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"responses":{"200":{"description":"Original result and committed_at"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"404":{"description":"No committed receipt"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Receipts"]}},"/operations/expense_create/{key}":{"get":{"operationId":"get_expense_create_receipt","summary":"Recover a committed expense create result","description":"Requires write:payroll_requests and the same API key. A missing receipt does not prove an in-flight request failed; retry it with the same key and bytes instead.","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"responses":{"200":{"description":"Original result and committed_at"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"404":{"description":"No committed receipt"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Receipts"]}},"/operations/time_off_create/{key}":{"get":{"operationId":"get_time_off_create_receipt","summary":"Recover a committed time off_create result","description":"Requires write:payroll_requests and the same API key. A missing receipt does not prove an in-flight request failed; retry it with the same key and bytes instead.","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"responses":{"200":{"description":"Original result and committed_at"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"404":{"description":"No committed receipt"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Receipts"]}},"/operations/document_create/{key}":{"get":{"operationId":"get_document_create_receipt","summary":"Recover a committed document create result","description":"Requires write:documents and the same API key. A missing receipt does not prove an in-flight request failed; retry it with the same key and bytes instead.","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"responses":{"200":{"description":"Original result and committed_at"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"404":{"description":"No committed receipt"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Receipts"]}},"/operations/crew_add/{key}":{"get":{"operationId":"get_crew_add_receipt","summary":"Recover a committed crew add result","description":"Requires write:task_crews and the same API key. A missing receipt does not prove an in-flight request failed; retry it with the same key and bytes instead.","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"responses":{"200":{"description":"Original result and committed_at"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"404":{"description":"No committed receipt"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Receipts"]}},"/operations/crew_remove/{key}":{"get":{"operationId":"get_crew_remove_receipt","summary":"Recover a committed crew remove result","description":"Requires write:task_crews and the same API key. A missing receipt does not prove an in-flight request failed; retry it with the same key and bytes instead.","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"responses":{"200":{"description":"Original result and committed_at"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"404":{"description":"No committed receipt"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Receipts"]}},"/operations/complaint_create/{key}":{"get":{"operationId":"get_complaint_create_receipt","summary":"Recover a committed complaint create result","description":"Requires write:complaints and the same API key. A missing receipt does not prove an in-flight request failed; retry it with the same key and bytes instead.","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"responses":{"200":{"description":"Original result and committed_at"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"404":{"description":"No committed receipt"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Receipts"]}},"/operations/complaint_update/{key}":{"get":{"operationId":"get_complaint_update_receipt","summary":"Recover a committed complaint update result","description":"Requires write:complaints and the same API key. A missing receipt does not prove an in-flight request failed; retry it with the same key and bytes instead.","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"responses":{"200":{"description":"Original result and committed_at"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"404":{"description":"No committed receipt"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Receipts"]}},"/operations/tag_create/{key}":{"get":{"operationId":"get_tag_create_receipt","summary":"Recover a committed tag create result","description":"Requires write:tags and the same API key. A missing receipt does not prove an in-flight request failed; retry it with the same key and bytes instead.","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"responses":{"200":{"description":"Original result and committed_at"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"404":{"description":"No committed receipt"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Receipts"]}},"/operations/tag_update/{key}":{"get":{"operationId":"get_tag_update_receipt","summary":"Recover a committed tag update result","description":"Requires write:tags and the same API key. A missing receipt does not prove an in-flight request failed; retry it with the same key and bytes instead.","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"responses":{"200":{"description":"Original result and committed_at"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"404":{"description":"No committed receipt"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Receipts"]}},"/operations/tag_delete/{key}":{"get":{"operationId":"get_tag_delete_receipt","summary":"Recover a committed tag delete result","description":"Requires write:tags and the same API key. A missing receipt does not prove an in-flight request failed; retry it with the same key and bytes instead.","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"responses":{"200":{"description":"Original result and committed_at"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"404":{"description":"No committed receipt"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Receipts"]}},"/operations/corporate_site_create/{key}":{"get":{"operationId":"get_corporate_site_create_receipt","summary":"Recover a committed corporate site_create result","description":"Requires write:corporate_accounts and the same API key. A missing receipt does not prove an in-flight request failed; retry it with the same key and bytes instead.","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"responses":{"200":{"description":"Original result and committed_at"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"404":{"description":"No committed receipt"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Receipts"]}},"/operations/corporate_unit_create/{key}":{"get":{"operationId":"get_corporate_unit_create_receipt","summary":"Recover a committed corporate unit_create result","description":"Requires write:corporate_accounts and the same API key. A missing receipt does not prove an in-flight request failed; retry it with the same key and bytes instead.","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"responses":{"200":{"description":"Original result and committed_at"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"404":{"description":"No committed receipt"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Receipts"]}},"/operations/corporate_unit_update/{key}":{"get":{"operationId":"get_corporate_unit_update_receipt","summary":"Recover a committed corporate unit_update result","description":"Requires write:corporate_accounts and the same API key. A missing receipt does not prove an in-flight request failed; retry it with the same key and bytes instead.","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"responses":{"200":{"description":"Original result and committed_at"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"404":{"description":"No committed receipt"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Receipts"]}},"/operations/corporate_tenant_add/{key}":{"get":{"operationId":"get_corporate_tenant_add_receipt","summary":"Recover a committed corporate tenant_add result","description":"Requires write:corporate_accounts and the same API key. A missing receipt does not prove an in-flight request failed; retry it with the same key and bytes instead.","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"responses":{"200":{"description":"Original result and committed_at"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"404":{"description":"No committed receipt"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Receipts"]}},"/operations/corporate_tenant_move_out/{key}":{"get":{"operationId":"get_corporate_tenant_move_out_receipt","summary":"Recover a committed corporate tenant_move_out result","description":"Requires write:corporate_accounts and the same API key. A missing receipt does not prove an in-flight request failed; retry it with the same key and bytes instead.","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"responses":{"200":{"description":"Original result and committed_at"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"404":{"description":"No committed receipt"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Receipts"]}},"/operations/corporate_request_create/{key}":{"get":{"operationId":"get_corporate_request_create_receipt","summary":"Recover a committed corporate request_create result","description":"Requires write:corporate_accounts and the same API key. A missing receipt does not prove an in-flight request failed; retry it with the same key and bytes instead.","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"responses":{"200":{"description":"Original result and committed_at"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"404":{"description":"No committed receipt"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Receipts"]}},"/operations/corporate_request_decide/{key}":{"get":{"operationId":"get_corporate_request_decide_receipt","summary":"Recover a committed corporate request_decide result","description":"Requires write:corporate_accounts and the same API key. A missing receipt does not prove an in-flight request failed; retry it with the same key and bytes instead.","parameters":[{"name":"key","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"responses":{"200":{"description":"Original result and committed_at"},"400":{"description":"Invalid target, Idempotency-Key or query"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope, record outside approved companies, or a company-restricted key for a shared catalog or equipment change"},"404":{"description":"No committed receipt"},"409":{"description":"Same key with different content, the record changed since you read it, or the record is still in use"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields or the record is in a state that does not allow this change"},"503":{"description":"Transaction unavailable; retry the same key and exact bytes"}},"tags":["Receipts"]}},"/deleted":{"get":{"operationId":"list_deleted_records","summary":"Change feed of deleted records","description":"Lists records deleted in the last 90 days (including customers removed by a merge), oldest first. Requires the same read permission as each resource returned; without a resource parameter every readable resource is included. Company-restricted keys see deletions in their companies plus the shared catalog; organization-wide resources need an unrestricted key. Recurring plan deletions appear as jobs and transcript deletions as calls. Child records removed together with their parent (for example chat messages with their chat) may appear only as the parent. To sync: store the time before each run, read records with updated_from=<last run> and this feed with since=<last run>, and remove the returned IDs locally.","parameters":[{"name":"resource","in":"query","schema":{"type":"string","enum":["contacts","jobs","tasks","quotes","invoices","payments","leads","services","products","companies","properties","employees","documents","agreements","warranties","cameras","treatments","treatment_products","credits","tags","schedules","collections","disputes","task_types","calls","call_summaries","text_messages","outbound_emails","inbound_emails","chats","chat_messages","timeline","timeline_replies","visit_form_answers","visit_assignments","inspection_reports","inspection_report_answers","work_signoffs","warranty_items","bait_stations","station_checks","traps","commissions","time_entries","complaints","online_bookings","variants","expenses","time_off_requests","reimbursements","campaigns","automations","forms","booking_widgets","chat_widgets","contractors","contractor_work_orders","corporate_accounts","corporate_sites","corporate_units","corporate_team_members","corporate_tenancies","corporate_requests","corporate_unit_prices","property_keys","property_key_events","service_reports","service_report_settings","card_expiry_notices","price_change_batches","plan_price_changes","plan_renewal_notices","monitoring_points","activity_observations","monitoring_actions","monitoring_reports","sales_contests"]}},{"name":"since","in":"query","schema":{"type":"string","format":"date-time"},"description":"Inclusive ISO 8601 timestamp, or a date at UTC midnight."},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":1000,"default":100}},{"name":"cursor","in":"query","schema":{"type":"string"},"description":"Opaque next_cursor from the previous page."}],"responses":{"200":{"description":"Deleted record IDs","content":{"application/json":{"schema":{"type":"object","required":["data","next_cursor","has_more"],"properties":{"data":{"type":"array","items":{"type":"object","properties":{"resource":{"type":"string"},"id":{"type":"string","format":"uuid"},"company_id":{"type":"string","format":"uuid","nullable":true},"deleted_at":{"type":"string","format":"date-time"}}}},"next_cursor":{"type":"string","nullable":true},"has_more":{"type":"boolean"}}}}}},"400":{"description":"Invalid parameters"},"401":{"description":"Missing, invalid, expired, or revoked key"},"403":{"description":"No read scope for the requested resources"}},"tags":["Sync & Deletions"]}},"/business-settings":{"get":{"operationId":"get_business_settings","summary":"Lead sources, sales tax and payment methods","description":"Requires read:settings. Returns lead sources and the sales tax rate for the organization (unrestricted keys only) and for each company you can access, showing whether each value is the company's own, inherited from the organization, or the built-in default. Also lists each company's card processors (name and default/test status only; never credentials) and the offline payment methods accepted by POST /payments. No query parameters.","responses":{"200":{"description":"Settings"},"401":{"description":"Missing or invalid key"},"403":{"description":"Missing scope"},"503":{"description":"Temporarily unavailable"}},"tags":["Business Settings"]}},"/webhook-events":{"get":{"operationId":"list_webhook_event_types","summary":"List every outbound webhook event type","description":"Any valid key. Returns each event name, group, description, the read permission needed to subscribe through the API, whether company-restricted endpoints receive it, and its summary data fields.","responses":{"200":{"description":"Event catalog","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object"}},"envelope_version":{"type":"string"}}}}}},"400":{"description":"Invalid parameters"},"401":{"description":"Missing, invalid, expired, or revoked key"},"403":{"description":"Missing scope, company-restricted key, or missing read scope for a subscribed event"},"404":{"description":"Not found in this organization"},"429":{"description":"Rate limit exceeded"},"503":{"description":"Temporarily unavailable; nothing is reported as success"}},"tags":["Outbound Webhooks"]}},"/webhook-endpoints":{"get":{"operationId":"list_webhook_endpoints","summary":"List outbound webhook endpoints","description":"Requires read:webhooks and unrestricted company access. Secrets are never returned.","parameters":[{"name":"include_deleted","in":"query","schema":{"type":"boolean","default":false}}],"responses":{"200":{"description":"Endpoints","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string","minLength":1,"maxLength":100},"url":{"type":"string","format":"uri","maxLength":2048,"description":"Public HTTPS URL on the default port. Redirects, private addresses and embedded credentials are refused."},"events":{"type":"array","minItems":1,"maxItems":200,"uniqueItems":true,"items":{"type":"string"},"description":"Event names from GET /webhook-events, a family wildcard such as job.*, or * for every event."},"description":{"type":"string","maxLength":500,"nullable":true},"headers":{"type":"object","maxProperties":20,"additionalProperties":{"type":"string","maxLength":1000},"description":"Extra request headers. Signature, event, content-type and transport headers cannot be overridden."},"payload_mode":{"type":"string","enum":["summary","full"],"default":"summary","description":"full adds the record's API summary as top-level record, read once before the first attempt."},"is_active":{"type":"boolean"},"company_ids":{"type":"array","items":{"type":"string","format":"uuid"},"nullable":true},"secret_hint":{"type":"string","nullable":true},"secret_rotated_at":{"type":"string","format":"date-time","nullable":true},"previous_secret_expires_at":{"type":"string","format":"date-time","nullable":true},"disabled_reason":{"type":"string","enum":["manual","auto_paused"],"nullable":true},"disabled_at":{"type":"string","format":"date-time","nullable":true},"health":{"type":"object","properties":{"consecutive_failures":{"type":"integer"},"failing_since":{"type":"string","format":"date-time","nullable":true},"last_success_at":{"type":"string","format":"date-time","nullable":true},"last_failure_at":{"type":"string","format":"date-time","nullable":true}}},"version":{"type":"integer"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"},"secret":{"type":"string","description":"Returned only when the endpoint is created (or the same creation is retried) and when the secret is rotated."}}}}}}}}},"400":{"description":"Invalid parameters"},"401":{"description":"Missing, invalid, expired, or revoked key"},"403":{"description":"Missing scope, company-restricted key, or missing read scope for a subscribed event"},"404":{"description":"Not found in this organization"},"429":{"description":"Rate limit exceeded"},"503":{"description":"Temporarily unavailable; nothing is reported as success"}},"tags":["Outbound Webhooks"]},"post":{"operationId":"create_webhook_endpoint","summary":"Create an outbound webhook endpoint","description":"Requires write:webhooks, unrestricted company access, and the read permission for every subscribed event. At most 25 endpoints per organization. Returns the signing secret; store it securely. Retrying with the same Idempotency-Key and exact body returns the original endpoint (200, replayed=true); a different body returns 409. company_ids restricts delivery to events of those companies and cannot be changed later.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["name","url","events"],"properties":{"name":{"type":"string","minLength":1,"maxLength":100},"url":{"type":"string","format":"uri","maxLength":2048,"description":"Public HTTPS URL on the default port. Redirects, private addresses and embedded credentials are refused."},"events":{"type":"array","minItems":1,"maxItems":200,"uniqueItems":true,"items":{"type":"string"},"description":"Event names from GET /webhook-events, a family wildcard such as job.*, or * for every event."},"description":{"type":"string","maxLength":500,"nullable":true},"headers":{"type":"object","maxProperties":20,"additionalProperties":{"type":"string","maxLength":1000},"description":"Extra request headers. Signature, event, content-type and transport headers cannot be overridden."},"payload_mode":{"type":"string","enum":["summary","full"],"default":"summary","description":"full adds the record's API summary as top-level record, read once before the first attempt."},"is_active":{"type":"boolean"},"company_ids":{"type":"array","items":{"type":"string","format":"uuid"},"minItems":1,"maxItems":100,"nullable":true}}}}}},"responses":{"200":{"description":"Original endpoint returned for a retried request"},"201":{"description":"Endpoint created; includes secret","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string","minLength":1,"maxLength":100},"url":{"type":"string","format":"uri","maxLength":2048,"description":"Public HTTPS URL on the default port. Redirects, private addresses and embedded credentials are refused."},"events":{"type":"array","minItems":1,"maxItems":200,"uniqueItems":true,"items":{"type":"string"},"description":"Event names from GET /webhook-events, a family wildcard such as job.*, or * for every event."},"description":{"type":"string","maxLength":500,"nullable":true},"headers":{"type":"object","maxProperties":20,"additionalProperties":{"type":"string","maxLength":1000},"description":"Extra request headers. Signature, event, content-type and transport headers cannot be overridden."},"payload_mode":{"type":"string","enum":["summary","full"],"default":"summary","description":"full adds the record's API summary as top-level record, read once before the first attempt."},"is_active":{"type":"boolean"},"company_ids":{"type":"array","items":{"type":"string","format":"uuid"},"nullable":true},"secret_hint":{"type":"string","nullable":true},"secret_rotated_at":{"type":"string","format":"date-time","nullable":true},"previous_secret_expires_at":{"type":"string","format":"date-time","nullable":true},"disabled_reason":{"type":"string","enum":["manual","auto_paused"],"nullable":true},"disabled_at":{"type":"string","format":"date-time","nullable":true},"health":{"type":"object","properties":{"consecutive_failures":{"type":"integer"},"failing_since":{"type":"string","format":"date-time","nullable":true},"last_success_at":{"type":"string","format":"date-time","nullable":true},"last_failure_at":{"type":"string","format":"date-time","nullable":true}}},"version":{"type":"integer"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"},"secret":{"type":"string","description":"Returned only when the endpoint is created (or the same creation is retried) and when the secret is rotated."}}},"replayed":{"type":"boolean"}}}}}},"400":{"description":"Invalid parameters"},"401":{"description":"Missing, invalid, expired, or revoked key"},"403":{"description":"Missing scope, company-restricted key, or missing read scope for a subscribed event"},"404":{"description":"Not found in this organization"},"409":{"description":"Idempotency-Key reused with a different body"},"415":{"description":"application/json required"},"422":{"description":"Invalid fields, unknown event, or endpoint limit reached"},"429":{"description":"Rate limit exceeded"},"503":{"description":"Temporarily unavailable; nothing is reported as success"}},"tags":["Outbound Webhooks"]}},"/webhook-endpoints/{id}":{"get":{"operationId":"get_webhook_endpoint","summary":"Read one endpoint","description":"Requires read:webhooks. Includes delivery health. Secrets are never returned.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Endpoint","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string","minLength":1,"maxLength":100},"url":{"type":"string","format":"uri","maxLength":2048,"description":"Public HTTPS URL on the default port. Redirects, private addresses and embedded credentials are refused."},"events":{"type":"array","minItems":1,"maxItems":200,"uniqueItems":true,"items":{"type":"string"},"description":"Event names from GET /webhook-events, a family wildcard such as job.*, or * for every event."},"description":{"type":"string","maxLength":500,"nullable":true},"headers":{"type":"object","maxProperties":20,"additionalProperties":{"type":"string","maxLength":1000},"description":"Extra request headers. Signature, event, content-type and transport headers cannot be overridden."},"payload_mode":{"type":"string","enum":["summary","full"],"default":"summary","description":"full adds the record's API summary as top-level record, read once before the first attempt."},"is_active":{"type":"boolean"},"company_ids":{"type":"array","items":{"type":"string","format":"uuid"},"nullable":true},"secret_hint":{"type":"string","nullable":true},"secret_rotated_at":{"type":"string","format":"date-time","nullable":true},"previous_secret_expires_at":{"type":"string","format":"date-time","nullable":true},"disabled_reason":{"type":"string","enum":["manual","auto_paused"],"nullable":true},"disabled_at":{"type":"string","format":"date-time","nullable":true},"health":{"type":"object","properties":{"consecutive_failures":{"type":"integer"},"failing_since":{"type":"string","format":"date-time","nullable":true},"last_success_at":{"type":"string","format":"date-time","nullable":true},"last_failure_at":{"type":"string","format":"date-time","nullable":true}}},"version":{"type":"integer"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"},"secret":{"type":"string","description":"Returned only when the endpoint is created (or the same creation is retried) and when the secret is rotated."}}}}}}}},"400":{"description":"Invalid parameters"},"401":{"description":"Missing, invalid, expired, or revoked key"},"403":{"description":"Missing scope, company-restricted key, or missing read scope for a subscribed event"},"404":{"description":"Not found in this organization"},"429":{"description":"Rate limit exceeded"},"503":{"description":"Temporarily unavailable; nothing is reported as success"}},"tags":["Outbound Webhooks"]},"patch":{"operationId":"update_webhook_endpoint","summary":"Update an endpoint","description":"Requires write:webhooks. Send the version you last read as expected_version; a changed endpoint returns 409 with nothing applied. Turning an auto-paused endpoint back on resets its failure streak; replay its failed deliveries afterwards. Company scope cannot change.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["expected_version"],"minProperties":2,"properties":{"expected_version":{"type":"integer","minimum":1},"name":{"type":"string","minLength":1,"maxLength":100},"url":{"type":"string","format":"uri","maxLength":2048,"description":"Public HTTPS URL on the default port. Redirects, private addresses and embedded credentials are refused."},"events":{"type":"array","minItems":1,"maxItems":200,"uniqueItems":true,"items":{"type":"string"},"description":"Event names from GET /webhook-events, a family wildcard such as job.*, or * for every event."},"description":{"type":"string","maxLength":500,"nullable":true},"headers":{"type":"object","maxProperties":20,"additionalProperties":{"type":"string","maxLength":1000},"description":"Extra request headers. Signature, event, content-type and transport headers cannot be overridden."},"payload_mode":{"type":"string","enum":["summary","full"],"default":"summary","description":"full adds the record's API summary as top-level record, read once before the first attempt."},"is_active":{"type":"boolean"}}}}}},"responses":{"200":{"description":"Updated endpoint"},"400":{"description":"Invalid parameters"},"401":{"description":"Missing, invalid, expired, or revoked key"},"403":{"description":"Missing scope, company-restricted key, or missing read scope for a subscribed event"},"404":{"description":"Not found in this organization"},"409":{"description":"Version changed; re-read before deciding"},"422":{"description":"Invalid fields"},"429":{"description":"Rate limit exceeded"},"503":{"description":"Temporarily unavailable; nothing is reported as success"}},"tags":["Outbound Webhooks"]},"delete":{"operationId":"delete_webhook_endpoint","summary":"Delete an endpoint","description":"Requires write:webhooks and expected_version. Stops all delivery immediately and keeps delivery history until it ages out of retention.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"expected_version","in":"query","required":true,"schema":{"type":"integer","minimum":1}}],"responses":{"200":{"description":"Endpoint deleted"},"400":{"description":"Invalid parameters"},"401":{"description":"Missing, invalid, expired, or revoked key"},"403":{"description":"Missing scope, company-restricted key, or missing read scope for a subscribed event"},"404":{"description":"Not found in this organization"},"409":{"description":"Version changed"},"429":{"description":"Rate limit exceeded"},"503":{"description":"Temporarily unavailable; nothing is reported as success"}},"tags":["Outbound Webhooks"]}},"/webhook-endpoints/{id}/rotate-secret":{"post":{"operationId":"rotate_webhook_secret","summary":"Rotate an endpoint's signing secret","description":"Requires write:webhooks and expected_version. Returns the new secret once. During overlap_hours (default 24, 0-168) every delivery is signed with both the new and previous secret, so receivers can switch without dropping events.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["expected_version"],"properties":{"expected_version":{"type":"integer","minimum":1},"overlap_hours":{"type":"integer","minimum":0,"maximum":168,"default":24}}}}}},"responses":{"200":{"description":"Endpoint with new secret"},"400":{"description":"Invalid parameters"},"401":{"description":"Missing, invalid, expired, or revoked key"},"403":{"description":"Missing scope, company-restricted key, or missing read scope for a subscribed event"},"404":{"description":"Not found in this organization"},"409":{"description":"Version changed"},"429":{"description":"Rate limit exceeded"},"503":{"description":"Temporarily unavailable; nothing is reported as success"}},"tags":["Outbound Webhooks"]}},"/webhook-endpoints/{id}/test":{"post":{"operationId":"send_webhook_test","summary":"Queue a test.ping event","description":"Requires write:webhooks. 202 means the test was queued, not delivered; check the delivery log.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"202":{"description":"Test queued"},"400":{"description":"Invalid parameters"},"401":{"description":"Missing, invalid, expired, or revoked key"},"403":{"description":"Missing scope, company-restricted key, or missing read scope for a subscribed event"},"404":{"description":"Not found in this organization"},"429":{"description":"Rate limit exceeded"},"503":{"description":"Temporarily unavailable; nothing is reported as success"}},"tags":["Outbound Webhooks"]}},"/webhook-deliveries":{"get":{"operationId":"list_webhook_deliveries","summary":"List delivery history","description":"Requires read:webhooks. Newest first. Succeeded and cancelled deliveries are kept 30 days; failed deliveries 90 days.","parameters":[{"name":"endpoint_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"state","in":"query","schema":{"type":"string","enum":["pending","processing","retry","succeeded","dead","cancelled","legacy"]}},{"name":"event_type","in":"query","schema":{"type":"string"}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Deliveries with next_cursor and has_more"},"400":{"description":"Invalid parameters"},"401":{"description":"Missing, invalid, expired, or revoked key"},"403":{"description":"Missing scope, company-restricted key, or missing read scope for a subscribed event"},"404":{"description":"Not found in this organization"},"429":{"description":"Rate limit exceeded"},"503":{"description":"Temporarily unavailable; nothing is reported as success"}},"tags":["Outbound Webhooks"]}},"/webhook-deliveries/{id}":{"get":{"operationId":"get_webhook_delivery","summary":"Read one delivery with its payload and every attempt","description":"Requires read:webhooks. Receiver response bodies are never stored.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Delivery detail"},"400":{"description":"Invalid parameters"},"401":{"description":"Missing, invalid, expired, or revoked key"},"403":{"description":"Missing scope, company-restricted key, or missing read scope for a subscribed event"},"404":{"description":"Not found in this organization"},"429":{"description":"Rate limit exceeded"},"503":{"description":"Temporarily unavailable; nothing is reported as success"}},"tags":["Outbound Webhooks"]}},"/webhook-deliveries/{id}/replay":{"post":{"operationId":"replay_webhook_delivery","summary":"Replay a failed or cancelled delivery","description":"Requires write:webhooks. Sends the identical event ID and body again with a fresh attempt cycle. The endpoint must be active.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"202":{"description":"Replay queued"},"400":{"description":"Invalid parameters"},"401":{"description":"Missing, invalid, expired, or revoked key"},"403":{"description":"Missing scope, company-restricted key, or missing read scope for a subscribed event"},"404":{"description":"Not found in this organization"},"409":{"description":"Delivery is not failed/cancelled or endpoint is inactive"},"429":{"description":"Rate limit exceeded"},"503":{"description":"Temporarily unavailable; nothing is reported as success"}},"tags":["Outbound Webhooks"]}}}}