{"openapi":"3.1.0","info":{"title":"Billet API","description":"Public REST API for Billet — delivery ticket, signature capture, and POD platform for distributors and supply companies. Every endpoint authenticates via an API key (Developer → API Keys in the dashboard) passed as `X-API-Key`. Requests are tenant-scoped to the owning company automatically.","version":"1.0.0","contact":{"name":"Billet Support","email":"support@billetsystems.com","url":"https://billetsystems.com"},"license":{"name":"Proprietary"}},"components":{"securitySchemes":{"ApiKey":{"type":"apiKey","in":"header","name":"X-API-Key","description":"Per-company API key. Create one at https://app.billetsystems.com/developer. Keys are tied to the issuing company and inherit the admin who created them for audit purposes."}},"schemas":{}},"paths":{"/api/v1/tickets":{"get":{"summary":"List tickets","tags":["Tickets"],"description":"Returns a paginated list of tickets for the authenticating company, most recent first. Supports filtering by status, customer, driver, date, and exact order number.","parameters":[{"schema":{"type":"integer","minimum":1,"default":1},"in":"query","name":"page","required":false,"description":"Page number (1-indexed)."},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":50},"in":"query","name":"per_page","required":false,"description":"Results per page. Max 100."},{"schema":{"type":"string","enum":["draft","assigned","in_transit","delivered","awaiting_signature","signed","archived","rejected","issue"]},"in":"query","name":"status","required":false,"description":"Only return tickets in this status."},{"schema":{"type":"string","format":"uuid"},"in":"query","name":"customer_id","required":false,"description":"Only tickets for a specific customer."},{"schema":{"type":"string","format":"uuid"},"in":"query","name":"driver_id","required":false,"description":"Only tickets assigned to a specific driver."},{"schema":{"type":"string","format":"date-time"},"in":"query","name":"since","required":false,"description":"Only tickets created on or after this timestamp."},{"schema":{"type":"string"},"in":"query","name":"order_number","required":false,"description":"Exact match on order number. Useful for idempotency checks before POST."}],"responses":{"200":{"description":"Page of tickets.","content":{"application/json":{"schema":{"description":"Page of tickets.","type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"order_number":{"type":"string","example":"SO-4521"},"status":{"type":"string","enum":["draft","assigned","in_transit","delivered","awaiting_signature","signed","archived","rejected","issue"]},"document_type":{"type":"string","enum":["delivery_ticket","invoice","soc","estimate","sales_receipt","transfer","bol"]},"order_date":{"type":"string","format":"date","example":"2026-04-21"},"invoice_total":{"type":["null","number"],"example":1247.5},"customer_id":{"type":["null","string"],"format":"uuid"},"customer_name":{"type":["null","string"],"example":"Acme Plumbing Supply"},"customer_number":{"type":["null","string"],"example":"15-0014125"},"driver_id":{"type":["null","string"],"format":"uuid"},"driver_name":{"type":["null","string"]},"driver_code":{"type":["null","string"],"example":"D1"},"customer_signature_name":{"type":["null","string"]},"customer_signed_at":{"type":["null","string"],"format":"date-time"},"gps_latitude":{"type":["null","number"],"example":32.7157},"gps_longitude":{"type":["null","number"],"example":-117.1611},"custom_fields":{"type":"object","additionalProperties":true},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}}},"meta":{"type":"object","description":"Pagination envelope. All v1 list endpoints return the same shape — page numbers start at 1, per_page defaults to 50 and caps at 100.","properties":{"page":{"type":"integer","example":1},"per_page":{"type":"integer","example":50},"total":{"type":"integer","example":247},"total_pages":{"type":"integer","example":5}}}}}}}},"401":{"description":"Missing, invalid, or deactivated API key.","content":{"application/json":{"schema":{"description":"Missing, invalid, or deactivated API key.","type":"object","properties":{"error":{"type":"string","description":"Human-readable error message (legacy alias for `title`)."},"title":{"type":"string","description":"Human-readable error message (RFC 9457)."},"status":{"type":"integer","description":"HTTP status code (RFC 9457)."},"statusCode":{"type":"integer","description":"HTTP status code (legacy alias for `status`)."},"type":{"type":"string","format":"uri","description":"URI pointing to the docs section for this error code (RFC 9457)."},"code":{"type":"string","description":"Machine-readable error code (stable identifier — see https://docs.billetsystems.com/errors)."},"request_id":{"type":"string","description":"Unique request identifier for support correlation."},"required_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the minimum tier needed to perform the operation."},"current_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the caller's current plan tier."},"errors":{"type":"array","description":"Per-field validation errors. Only present on 400 / 422 validation failures.","items":{"type":"object","properties":{"field":{"type":"string","description":"Dotted path of the failing field (e.g. `line_items.0.sku`)."},"message":{"type":"string","description":"Static, input-free description of the failure."},"code":{"type":"string","description":"Fixed-vocabulary field code — one of REQUIRED / INVALID_FORMAT / TOO_LONG / TOO_SHORT / TOO_BIG / TOO_SMALL / NOT_UNIQUE / INVALID_VALUE / TIER_LIMIT_EXCEEDED."}}}}},"required":["error"]}}}}}},"post":{"summary":"Create a ticket","tags":["Tickets"],"description":"Creates a new delivery ticket, invoice, estimate, SOC, or other document. The customer is upserted by `customer_number` (or generated if omitted). `order_number` is optional — Billet auto-generates one from the company's configured format (default `INV-{seq:6}`) when not supplied. Fires a `ticket.created` webhook to every subscribed endpoint. Line items are optional — many ERPs push headers only and attach items in a follow-up call.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["customer_name"],"additionalProperties":false,"properties":{"order_number":{"type":"string","minLength":1,"maxLength":100},"customer_name":{"type":"string","minLength":1,"maxLength":200},"customer_number":{"type":"string","maxLength":100},"order_date":{"type":"string","maxLength":30},"invoice_number":{"type":"string","maxLength":100},"document_type":{"type":"string","enum":["delivery_ticket","invoice","soc","estimate","sales_receipt","transfer","bol"]},"confirm_to":{"type":"string","maxLength":200},"customer_po":{"type":"string","maxLength":100},"ship_via":{"type":"string","maxLength":100},"fob":{"type":"string","maxLength":100},"terms":{"type":"string","maxLength":200},"delivery_notes":{"type":"string","maxLength":2000},"address_line1":{"type":"string","maxLength":200},"city":{"type":"string","maxLength":100},"state":{"type":"string","maxLength":100},"zip":{"type":"string","maxLength":20},"location_name":{"type":"string","maxLength":200},"salesperson_code":{"type":"string","maxLength":50},"driver_id":{"type":"string","format":"uuid","pattern":"^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$"},"net_invoice":{"type":"number"},"discount":{"type":"number"},"freight":{"type":"number"},"tax":{"type":"number"},"invoice_total":{"type":"number"},"branch_id":{"type":"string","format":"uuid","pattern":"^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$"},"custom_fields":{"type":"object","maxProperties":50},"line_items":{"type":"array","maxItems":200,"items":{"type":"object","properties":{"item_codes":{"type":"string","maxLength":100},"description":{"type":"string","maxLength":500},"quantity_shipped":{"type":"number"},"quantity_delivered":{"type":"number"},"price":{"type":"number"},"amount":{"type":"number"},"serials":{"type":"string","maxLength":500}}}}}}}}},"responses":{"201":{"description":"Ticket created.","content":{"application/json":{"schema":{"description":"Ticket created.","type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"order_number":{"type":"string"},"status":{"type":"string","enum":["draft","assigned"]}}}}}}}},"400":{"description":"Malformed request — bad JSON, wrong type, missing required field, or pattern mismatch. `errors[]` enumerates every failing field.","content":{"application/json":{"schema":{"description":"Malformed request — bad JSON, wrong type, missing required field, or pattern mismatch. `errors[]` enumerates every failing field.","type":"object","properties":{"error":{"type":"string","description":"Human-readable error message (legacy alias for `title`)."},"title":{"type":"string","description":"Human-readable error message (RFC 9457)."},"status":{"type":"integer","description":"HTTP status code (RFC 9457)."},"statusCode":{"type":"integer","description":"HTTP status code (legacy alias for `status`)."},"type":{"type":"string","format":"uri","description":"URI pointing to the docs section for this error code (RFC 9457)."},"code":{"type":"string","description":"Machine-readable error code (stable identifier — see https://docs.billetsystems.com/errors)."},"request_id":{"type":"string","description":"Unique request identifier for support correlation."},"required_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the minimum tier needed to perform the operation."},"current_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the caller's current plan tier."},"errors":{"type":"array","description":"Per-field validation errors. Only present on 400 / 422 validation failures.","items":{"type":"object","properties":{"field":{"type":"string","description":"Dotted path of the failing field (e.g. `line_items.0.sku`)."},"message":{"type":"string","description":"Static, input-free description of the failure."},"code":{"type":"string","description":"Fixed-vocabulary field code — one of REQUIRED / INVALID_FORMAT / TOO_LONG / TOO_SHORT / TOO_BIG / TOO_SMALL / NOT_UNIQUE / INVALID_VALUE / TIER_LIMIT_EXCEEDED."}}}}},"required":["error"]}}}},"401":{"description":"Missing, invalid, or deactivated API key.","content":{"application/json":{"schema":{"description":"Missing, invalid, or deactivated API key.","type":"object","properties":{"error":{"type":"string","description":"Human-readable error message (legacy alias for `title`)."},"title":{"type":"string","description":"Human-readable error message (RFC 9457)."},"status":{"type":"integer","description":"HTTP status code (RFC 9457)."},"statusCode":{"type":"integer","description":"HTTP status code (legacy alias for `status`)."},"type":{"type":"string","format":"uri","description":"URI pointing to the docs section for this error code (RFC 9457)."},"code":{"type":"string","description":"Machine-readable error code (stable identifier — see https://docs.billetsystems.com/errors)."},"request_id":{"type":"string","description":"Unique request identifier for support correlation."},"required_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the minimum tier needed to perform the operation."},"current_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the caller's current plan tier."},"errors":{"type":"array","description":"Per-field validation errors. Only present on 400 / 422 validation failures.","items":{"type":"object","properties":{"field":{"type":"string","description":"Dotted path of the failing field (e.g. `line_items.0.sku`)."},"message":{"type":"string","description":"Static, input-free description of the failure."},"code":{"type":"string","description":"Fixed-vocabulary field code — one of REQUIRED / INVALID_FORMAT / TOO_LONG / TOO_SHORT / TOO_BIG / TOO_SMALL / NOT_UNIQUE / INVALID_VALUE / TIER_LIMIT_EXCEEDED."}}}}},"required":["error"]}}}},"403":{"description":"Caller is authenticated but the current plan tier does not allow this operation (see `code: TIER_REQUIRED`).","content":{"application/json":{"schema":{"description":"Caller is authenticated but the current plan tier does not allow this operation (see `code: TIER_REQUIRED`).","type":"object","properties":{"error":{"type":"string","description":"Human-readable error message (legacy alias for `title`)."},"title":{"type":"string","description":"Human-readable error message (RFC 9457)."},"status":{"type":"integer","description":"HTTP status code (RFC 9457)."},"statusCode":{"type":"integer","description":"HTTP status code (legacy alias for `status`)."},"type":{"type":"string","format":"uri","description":"URI pointing to the docs section for this error code (RFC 9457)."},"code":{"type":"string","description":"Machine-readable error code (stable identifier — see https://docs.billetsystems.com/errors)."},"request_id":{"type":"string","description":"Unique request identifier for support correlation."},"required_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the minimum tier needed to perform the operation."},"current_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the caller's current plan tier."},"errors":{"type":"array","description":"Per-field validation errors. Only present on 400 / 422 validation failures.","items":{"type":"object","properties":{"field":{"type":"string","description":"Dotted path of the failing field (e.g. `line_items.0.sku`)."},"message":{"type":"string","description":"Static, input-free description of the failure."},"code":{"type":"string","description":"Fixed-vocabulary field code — one of REQUIRED / INVALID_FORMAT / TOO_LONG / TOO_SHORT / TOO_BIG / TOO_SMALL / NOT_UNIQUE / INVALID_VALUE / TIER_LIMIT_EXCEEDED."}}}}},"required":["error"]}}}},"409":{"description":"Conflict — duplicate `order_number` on ticket create, duplicate `customer_number` on customer create, or a concurrent request with the same `Idempotency-Key` is already in progress.","content":{"application/json":{"schema":{"description":"Conflict — duplicate `order_number` on ticket create, duplicate `customer_number` on customer create, or a concurrent request with the same `Idempotency-Key` is already in progress.","type":"object","properties":{"error":{"type":"string","description":"Human-readable error message (legacy alias for `title`)."},"title":{"type":"string","description":"Human-readable error message (RFC 9457)."},"status":{"type":"integer","description":"HTTP status code (RFC 9457)."},"statusCode":{"type":"integer","description":"HTTP status code (legacy alias for `status`)."},"type":{"type":"string","format":"uri","description":"URI pointing to the docs section for this error code (RFC 9457)."},"code":{"type":"string","description":"Machine-readable error code (stable identifier — see https://docs.billetsystems.com/errors)."},"request_id":{"type":"string","description":"Unique request identifier for support correlation."},"required_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the minimum tier needed to perform the operation."},"current_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the caller's current plan tier."},"errors":{"type":"array","description":"Per-field validation errors. Only present on 400 / 422 validation failures.","items":{"type":"object","properties":{"field":{"type":"string","description":"Dotted path of the failing field (e.g. `line_items.0.sku`)."},"message":{"type":"string","description":"Static, input-free description of the failure."},"code":{"type":"string","description":"Fixed-vocabulary field code — one of REQUIRED / INVALID_FORMAT / TOO_LONG / TOO_SHORT / TOO_BIG / TOO_SMALL / NOT_UNIQUE / INVALID_VALUE / TIER_LIMIT_EXCEEDED."}}}}},"required":["error"]}}}},"422":{"description":"Custom field values failed validation against the company schema.","content":{"application/json":{"schema":{"description":"Custom field values failed validation against the company schema.","type":"object","properties":{"error":{"type":"string","description":"Human-readable error message (legacy alias for `title`)."},"title":{"type":"string","description":"Human-readable error message (RFC 9457)."},"status":{"type":"integer","description":"HTTP status code (RFC 9457)."},"statusCode":{"type":"integer","description":"HTTP status code (legacy alias for `status`)."},"type":{"type":"string","format":"uri","description":"URI pointing to the docs section for this error code (RFC 9457)."},"code":{"type":"string","description":"Machine-readable error code (stable identifier — see https://docs.billetsystems.com/errors)."},"request_id":{"type":"string","description":"Unique request identifier for support correlation."},"required_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the minimum tier needed to perform the operation."},"current_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the caller's current plan tier."},"errors":{"type":"array","description":"Per-field validation errors. Only present on 400 / 422 validation failures.","items":{"type":"object","properties":{"field":{"type":"string","description":"Dotted path of the failing field (e.g. `line_items.0.sku`)."},"message":{"type":"string","description":"Static, input-free description of the failure."},"code":{"type":"string","description":"Fixed-vocabulary field code — one of REQUIRED / INVALID_FORMAT / TOO_LONG / TOO_SHORT / TOO_BIG / TOO_SMALL / NOT_UNIQUE / INVALID_VALUE / TIER_LIMIT_EXCEEDED."}}}}},"required":["error"]}}}},"500":{"description":"Unexpected server error creating the ticket.","content":{"application/json":{"schema":{"description":"Unexpected server error creating the ticket.","type":"object","properties":{"error":{"type":"string","description":"Human-readable error message (legacy alias for `title`)."},"title":{"type":"string","description":"Human-readable error message (RFC 9457)."},"status":{"type":"integer","description":"HTTP status code (RFC 9457)."},"statusCode":{"type":"integer","description":"HTTP status code (legacy alias for `status`)."},"type":{"type":"string","format":"uri","description":"URI pointing to the docs section for this error code (RFC 9457)."},"code":{"type":"string","description":"Machine-readable error code (stable identifier — see https://docs.billetsystems.com/errors)."},"request_id":{"type":"string","description":"Unique request identifier for support correlation."},"required_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the minimum tier needed to perform the operation."},"current_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the caller's current plan tier."},"errors":{"type":"array","description":"Per-field validation errors. Only present on 400 / 422 validation failures.","items":{"type":"object","properties":{"field":{"type":"string","description":"Dotted path of the failing field (e.g. `line_items.0.sku`)."},"message":{"type":"string","description":"Static, input-free description of the failure."},"code":{"type":"string","description":"Fixed-vocabulary field code — one of REQUIRED / INVALID_FORMAT / TOO_LONG / TOO_SHORT / TOO_BIG / TOO_SMALL / NOT_UNIQUE / INVALID_VALUE / TIER_LIMIT_EXCEEDED."}}}}},"required":["error"]}}}}}}},"/api/v1/tickets/{id}":{"get":{"summary":"Get a ticket by id","tags":["Tickets"],"description":"Returns the full ticket record including line items, photo count, signature block, and nested customer + location + driver objects. Unlike the list endpoint, this returns the complete ticket with line items suitable for detail pages.","parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Full ticket record.","content":{"application/json":{"schema":{"description":"Full ticket record.","type":"object","properties":{"data":{"type":"object","description":"Ticket with nested customer, location, driver, items, and signature.","additionalProperties":true}}}}}},"401":{"description":"Missing, invalid, or deactivated API key.","content":{"application/json":{"schema":{"description":"Missing, invalid, or deactivated API key.","type":"object","properties":{"error":{"type":"string","description":"Human-readable error message (legacy alias for `title`)."},"title":{"type":"string","description":"Human-readable error message (RFC 9457)."},"status":{"type":"integer","description":"HTTP status code (RFC 9457)."},"statusCode":{"type":"integer","description":"HTTP status code (legacy alias for `status`)."},"type":{"type":"string","format":"uri","description":"URI pointing to the docs section for this error code (RFC 9457)."},"code":{"type":"string","description":"Machine-readable error code (stable identifier — see https://docs.billetsystems.com/errors)."},"request_id":{"type":"string","description":"Unique request identifier for support correlation."},"required_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the minimum tier needed to perform the operation."},"current_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the caller's current plan tier."},"errors":{"type":"array","description":"Per-field validation errors. Only present on 400 / 422 validation failures.","items":{"type":"object","properties":{"field":{"type":"string","description":"Dotted path of the failing field (e.g. `line_items.0.sku`)."},"message":{"type":"string","description":"Static, input-free description of the failure."},"code":{"type":"string","description":"Fixed-vocabulary field code — one of REQUIRED / INVALID_FORMAT / TOO_LONG / TOO_SHORT / TOO_BIG / TOO_SMALL / NOT_UNIQUE / INVALID_VALUE / TIER_LIMIT_EXCEEDED."}}}}},"required":["error"]}}}},"404":{"description":"Resource not found, or not owned by the authenticating company.","content":{"application/json":{"schema":{"description":"Resource not found, or not owned by the authenticating company.","type":"object","properties":{"error":{"type":"string","description":"Human-readable error message (legacy alias for `title`)."},"title":{"type":"string","description":"Human-readable error message (RFC 9457)."},"status":{"type":"integer","description":"HTTP status code (RFC 9457)."},"statusCode":{"type":"integer","description":"HTTP status code (legacy alias for `status`)."},"type":{"type":"string","format":"uri","description":"URI pointing to the docs section for this error code (RFC 9457)."},"code":{"type":"string","description":"Machine-readable error code (stable identifier — see https://docs.billetsystems.com/errors)."},"request_id":{"type":"string","description":"Unique request identifier for support correlation."},"required_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the minimum tier needed to perform the operation."},"current_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the caller's current plan tier."},"errors":{"type":"array","description":"Per-field validation errors. Only present on 400 / 422 validation failures.","items":{"type":"object","properties":{"field":{"type":"string","description":"Dotted path of the failing field (e.g. `line_items.0.sku`)."},"message":{"type":"string","description":"Static, input-free description of the failure."},"code":{"type":"string","description":"Fixed-vocabulary field code — one of REQUIRED / INVALID_FORMAT / TOO_LONG / TOO_SHORT / TOO_BIG / TOO_SMALL / NOT_UNIQUE / INVALID_VALUE / TIER_LIMIT_EXCEEDED."}}}}},"required":["error"]}}}}}},"put":{"summary":"Update a ticket","tags":["Tickets"],"description":"Updates allowed fields on a ticket (only `draft` or `assigned` status tickets can be updated — signed / delivered tickets are frozen). Fires `ticket.updated` with `changed_fields` listing the modified keys. If the ticket is linked to an accounting provider (QB / Xero / FB / Dynamics), the edit is pushed upstream.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"order_number":{"type":"string","maxLength":100},"order_date":{"type":"string","maxLength":30},"invoice_number":{"type":"string","maxLength":100},"document_type":{"type":"string","enum":["delivery_ticket","invoice","soc","estimate","sales_receipt","transfer","bol"]},"confirm_to":{"type":"string","maxLength":200},"customer_po":{"type":"string","maxLength":100},"ship_via":{"type":"string","maxLength":100},"fob":{"type":"string","maxLength":100},"terms":{"type":"string","maxLength":200},"delivery_notes":{"type":"string","maxLength":2000},"due_date":{"type":["string","null"],"maxLength":30},"net_invoice":{"type":"number"},"discount":{"type":"number"},"freight":{"type":"number"},"tax":{"type":"number"},"invoice_total":{"type":"number"},"custom_fields":{"type":"object","maxProperties":50}}}}}},"parameters":[{"schema":{"type":"string","format":"uuid","pattern":"^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Ticket updated.","content":{"application/json":{"schema":{"description":"Ticket updated.","type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"updated":{"type":"array","items":{"type":"string"},"example":["terms","ship_via"]}}}}}}}},"400":{"description":"Malformed request — bad JSON, wrong type, missing required field, or pattern mismatch. `errors[]` enumerates every failing field.","content":{"application/json":{"schema":{"description":"Malformed request — bad JSON, wrong type, missing required field, or pattern mismatch. `errors[]` enumerates every failing field.","type":"object","properties":{"error":{"type":"string","description":"Human-readable error message (legacy alias for `title`)."},"title":{"type":"string","description":"Human-readable error message (RFC 9457)."},"status":{"type":"integer","description":"HTTP status code (RFC 9457)."},"statusCode":{"type":"integer","description":"HTTP status code (legacy alias for `status`)."},"type":{"type":"string","format":"uri","description":"URI pointing to the docs section for this error code (RFC 9457)."},"code":{"type":"string","description":"Machine-readable error code (stable identifier — see https://docs.billetsystems.com/errors)."},"request_id":{"type":"string","description":"Unique request identifier for support correlation."},"required_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the minimum tier needed to perform the operation."},"current_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the caller's current plan tier."},"errors":{"type":"array","description":"Per-field validation errors. Only present on 400 / 422 validation failures.","items":{"type":"object","properties":{"field":{"type":"string","description":"Dotted path of the failing field (e.g. `line_items.0.sku`)."},"message":{"type":"string","description":"Static, input-free description of the failure."},"code":{"type":"string","description":"Fixed-vocabulary field code — one of REQUIRED / INVALID_FORMAT / TOO_LONG / TOO_SHORT / TOO_BIG / TOO_SMALL / NOT_UNIQUE / INVALID_VALUE / TIER_LIMIT_EXCEEDED."}}}}},"required":["error"]}}}},"401":{"description":"Missing, invalid, or deactivated API key.","content":{"application/json":{"schema":{"description":"Missing, invalid, or deactivated API key.","type":"object","properties":{"error":{"type":"string","description":"Human-readable error message (legacy alias for `title`)."},"title":{"type":"string","description":"Human-readable error message (RFC 9457)."},"status":{"type":"integer","description":"HTTP status code (RFC 9457)."},"statusCode":{"type":"integer","description":"HTTP status code (legacy alias for `status`)."},"type":{"type":"string","format":"uri","description":"URI pointing to the docs section for this error code (RFC 9457)."},"code":{"type":"string","description":"Machine-readable error code (stable identifier — see https://docs.billetsystems.com/errors)."},"request_id":{"type":"string","description":"Unique request identifier for support correlation."},"required_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the minimum tier needed to perform the operation."},"current_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the caller's current plan tier."},"errors":{"type":"array","description":"Per-field validation errors. Only present on 400 / 422 validation failures.","items":{"type":"object","properties":{"field":{"type":"string","description":"Dotted path of the failing field (e.g. `line_items.0.sku`)."},"message":{"type":"string","description":"Static, input-free description of the failure."},"code":{"type":"string","description":"Fixed-vocabulary field code — one of REQUIRED / INVALID_FORMAT / TOO_LONG / TOO_SHORT / TOO_BIG / TOO_SMALL / NOT_UNIQUE / INVALID_VALUE / TIER_LIMIT_EXCEEDED."}}}}},"required":["error"]}}}},"404":{"description":"Resource not found, or not owned by the authenticating company.","content":{"application/json":{"schema":{"description":"Resource not found, or not owned by the authenticating company.","type":"object","properties":{"error":{"type":"string","description":"Human-readable error message (legacy alias for `title`)."},"title":{"type":"string","description":"Human-readable error message (RFC 9457)."},"status":{"type":"integer","description":"HTTP status code (RFC 9457)."},"statusCode":{"type":"integer","description":"HTTP status code (legacy alias for `status`)."},"type":{"type":"string","format":"uri","description":"URI pointing to the docs section for this error code (RFC 9457)."},"code":{"type":"string","description":"Machine-readable error code (stable identifier — see https://docs.billetsystems.com/errors)."},"request_id":{"type":"string","description":"Unique request identifier for support correlation."},"required_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the minimum tier needed to perform the operation."},"current_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the caller's current plan tier."},"errors":{"type":"array","description":"Per-field validation errors. Only present on 400 / 422 validation failures.","items":{"type":"object","properties":{"field":{"type":"string","description":"Dotted path of the failing field (e.g. `line_items.0.sku`)."},"message":{"type":"string","description":"Static, input-free description of the failure."},"code":{"type":"string","description":"Fixed-vocabulary field code — one of REQUIRED / INVALID_FORMAT / TOO_LONG / TOO_SHORT / TOO_BIG / TOO_SMALL / NOT_UNIQUE / INVALID_VALUE / TIER_LIMIT_EXCEEDED."}}}}},"required":["error"]}}}},"422":{"description":"Custom field values failed validation against the company schema.","content":{"application/json":{"schema":{"description":"Custom field values failed validation against the company schema.","type":"object","properties":{"error":{"type":"string","description":"Human-readable error message (legacy alias for `title`)."},"title":{"type":"string","description":"Human-readable error message (RFC 9457)."},"status":{"type":"integer","description":"HTTP status code (RFC 9457)."},"statusCode":{"type":"integer","description":"HTTP status code (legacy alias for `status`)."},"type":{"type":"string","format":"uri","description":"URI pointing to the docs section for this error code (RFC 9457)."},"code":{"type":"string","description":"Machine-readable error code (stable identifier — see https://docs.billetsystems.com/errors)."},"request_id":{"type":"string","description":"Unique request identifier for support correlation."},"required_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the minimum tier needed to perform the operation."},"current_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the caller's current plan tier."},"errors":{"type":"array","description":"Per-field validation errors. Only present on 400 / 422 validation failures.","items":{"type":"object","properties":{"field":{"type":"string","description":"Dotted path of the failing field (e.g. `line_items.0.sku`)."},"message":{"type":"string","description":"Static, input-free description of the failure."},"code":{"type":"string","description":"Fixed-vocabulary field code — one of REQUIRED / INVALID_FORMAT / TOO_LONG / TOO_SHORT / TOO_BIG / TOO_SMALL / NOT_UNIQUE / INVALID_VALUE / TIER_LIMIT_EXCEEDED."}}}}},"required":["error"]}}}}}},"delete":{"summary":"Delete a ticket","tags":["Tickets"],"description":"Hard-deletes a ticket. Only `draft` or `assigned` tickets can be deleted — signed / delivered / archived tickets are protected because they represent legally significant records. Fires `ticket.deleted`. Line items and photos are cascade-deleted.","parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Ticket deleted.","content":{"application/json":{"schema":{"description":"Ticket deleted.","type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"deleted":{"type":"boolean","example":true}}}}}}}},"400":{"description":"Malformed request — bad JSON, wrong type, missing required field, or pattern mismatch. `errors[]` enumerates every failing field.","content":{"application/json":{"schema":{"description":"Malformed request — bad JSON, wrong type, missing required field, or pattern mismatch. `errors[]` enumerates every failing field.","type":"object","properties":{"error":{"type":"string","description":"Human-readable error message (legacy alias for `title`)."},"title":{"type":"string","description":"Human-readable error message (RFC 9457)."},"status":{"type":"integer","description":"HTTP status code (RFC 9457)."},"statusCode":{"type":"integer","description":"HTTP status code (legacy alias for `status`)."},"type":{"type":"string","format":"uri","description":"URI pointing to the docs section for this error code (RFC 9457)."},"code":{"type":"string","description":"Machine-readable error code (stable identifier — see https://docs.billetsystems.com/errors)."},"request_id":{"type":"string","description":"Unique request identifier for support correlation."},"required_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the minimum tier needed to perform the operation."},"current_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the caller's current plan tier."},"errors":{"type":"array","description":"Per-field validation errors. Only present on 400 / 422 validation failures.","items":{"type":"object","properties":{"field":{"type":"string","description":"Dotted path of the failing field (e.g. `line_items.0.sku`)."},"message":{"type":"string","description":"Static, input-free description of the failure."},"code":{"type":"string","description":"Fixed-vocabulary field code — one of REQUIRED / INVALID_FORMAT / TOO_LONG / TOO_SHORT / TOO_BIG / TOO_SMALL / NOT_UNIQUE / INVALID_VALUE / TIER_LIMIT_EXCEEDED."}}}}},"required":["error"]}}}},"401":{"description":"Missing, invalid, or deactivated API key.","content":{"application/json":{"schema":{"description":"Missing, invalid, or deactivated API key.","type":"object","properties":{"error":{"type":"string","description":"Human-readable error message (legacy alias for `title`)."},"title":{"type":"string","description":"Human-readable error message (RFC 9457)."},"status":{"type":"integer","description":"HTTP status code (RFC 9457)."},"statusCode":{"type":"integer","description":"HTTP status code (legacy alias for `status`)."},"type":{"type":"string","format":"uri","description":"URI pointing to the docs section for this error code (RFC 9457)."},"code":{"type":"string","description":"Machine-readable error code (stable identifier — see https://docs.billetsystems.com/errors)."},"request_id":{"type":"string","description":"Unique request identifier for support correlation."},"required_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the minimum tier needed to perform the operation."},"current_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the caller's current plan tier."},"errors":{"type":"array","description":"Per-field validation errors. Only present on 400 / 422 validation failures.","items":{"type":"object","properties":{"field":{"type":"string","description":"Dotted path of the failing field (e.g. `line_items.0.sku`)."},"message":{"type":"string","description":"Static, input-free description of the failure."},"code":{"type":"string","description":"Fixed-vocabulary field code — one of REQUIRED / INVALID_FORMAT / TOO_LONG / TOO_SHORT / TOO_BIG / TOO_SMALL / NOT_UNIQUE / INVALID_VALUE / TIER_LIMIT_EXCEEDED."}}}}},"required":["error"]}}}},"404":{"description":"Resource not found, or not owned by the authenticating company.","content":{"application/json":{"schema":{"description":"Resource not found, or not owned by the authenticating company.","type":"object","properties":{"error":{"type":"string","description":"Human-readable error message (legacy alias for `title`)."},"title":{"type":"string","description":"Human-readable error message (RFC 9457)."},"status":{"type":"integer","description":"HTTP status code (RFC 9457)."},"statusCode":{"type":"integer","description":"HTTP status code (legacy alias for `status`)."},"type":{"type":"string","format":"uri","description":"URI pointing to the docs section for this error code (RFC 9457)."},"code":{"type":"string","description":"Machine-readable error code (stable identifier — see https://docs.billetsystems.com/errors)."},"request_id":{"type":"string","description":"Unique request identifier for support correlation."},"required_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the minimum tier needed to perform the operation."},"current_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the caller's current plan tier."},"errors":{"type":"array","description":"Per-field validation errors. Only present on 400 / 422 validation failures.","items":{"type":"object","properties":{"field":{"type":"string","description":"Dotted path of the failing field (e.g. `line_items.0.sku`)."},"message":{"type":"string","description":"Static, input-free description of the failure."},"code":{"type":"string","description":"Fixed-vocabulary field code — one of REQUIRED / INVALID_FORMAT / TOO_LONG / TOO_SHORT / TOO_BIG / TOO_SMALL / NOT_UNIQUE / INVALID_VALUE / TIER_LIMIT_EXCEEDED."}}}}},"required":["error"]}}}}}}},"/api/v1/tickets/{id}/assign":{"put":{"summary":"Assign a driver to a ticket","tags":["Tickets"],"description":"Assigns a driver (or salesperson / can-deliver user) to an existing ticket and flips its status to `assigned`. Fires a `ticket.assigned` webhook and, if the driver has push notifications enabled, sends them a mobile push. Use GET /drivers to get valid driver_ids.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["driver_id"],"additionalProperties":false,"properties":{"driver_id":{"type":"string","format":"uuid","pattern":"^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$"}}}}}},"parameters":[{"schema":{"type":"string","format":"uuid","pattern":"^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Ticket assigned.","content":{"application/json":{"schema":{"description":"Ticket assigned.","type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"status":{"type":"string","example":"assigned"},"driver_id":{"type":"string","format":"uuid"},"driver_name":{"type":"string"}}}}}}}},"400":{"description":"Malformed request — bad JSON, wrong type, missing required field, or pattern mismatch. `errors[]` enumerates every failing field.","content":{"application/json":{"schema":{"description":"Malformed request — bad JSON, wrong type, missing required field, or pattern mismatch. `errors[]` enumerates every failing field.","type":"object","properties":{"error":{"type":"string","description":"Human-readable error message (legacy alias for `title`)."},"title":{"type":"string","description":"Human-readable error message (RFC 9457)."},"status":{"type":"integer","description":"HTTP status code (RFC 9457)."},"statusCode":{"type":"integer","description":"HTTP status code (legacy alias for `status`)."},"type":{"type":"string","format":"uri","description":"URI pointing to the docs section for this error code (RFC 9457)."},"code":{"type":"string","description":"Machine-readable error code (stable identifier — see https://docs.billetsystems.com/errors)."},"request_id":{"type":"string","description":"Unique request identifier for support correlation."},"required_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the minimum tier needed to perform the operation."},"current_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the caller's current plan tier."},"errors":{"type":"array","description":"Per-field validation errors. Only present on 400 / 422 validation failures.","items":{"type":"object","properties":{"field":{"type":"string","description":"Dotted path of the failing field (e.g. `line_items.0.sku`)."},"message":{"type":"string","description":"Static, input-free description of the failure."},"code":{"type":"string","description":"Fixed-vocabulary field code — one of REQUIRED / INVALID_FORMAT / TOO_LONG / TOO_SHORT / TOO_BIG / TOO_SMALL / NOT_UNIQUE / INVALID_VALUE / TIER_LIMIT_EXCEEDED."}}}}},"required":["error"]}}}},"401":{"description":"Missing, invalid, or deactivated API key.","content":{"application/json":{"schema":{"description":"Missing, invalid, or deactivated API key.","type":"object","properties":{"error":{"type":"string","description":"Human-readable error message (legacy alias for `title`)."},"title":{"type":"string","description":"Human-readable error message (RFC 9457)."},"status":{"type":"integer","description":"HTTP status code (RFC 9457)."},"statusCode":{"type":"integer","description":"HTTP status code (legacy alias for `status`)."},"type":{"type":"string","format":"uri","description":"URI pointing to the docs section for this error code (RFC 9457)."},"code":{"type":"string","description":"Machine-readable error code (stable identifier — see https://docs.billetsystems.com/errors)."},"request_id":{"type":"string","description":"Unique request identifier for support correlation."},"required_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the minimum tier needed to perform the operation."},"current_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the caller's current plan tier."},"errors":{"type":"array","description":"Per-field validation errors. Only present on 400 / 422 validation failures.","items":{"type":"object","properties":{"field":{"type":"string","description":"Dotted path of the failing field (e.g. `line_items.0.sku`)."},"message":{"type":"string","description":"Static, input-free description of the failure."},"code":{"type":"string","description":"Fixed-vocabulary field code — one of REQUIRED / INVALID_FORMAT / TOO_LONG / TOO_SHORT / TOO_BIG / TOO_SMALL / NOT_UNIQUE / INVALID_VALUE / TIER_LIMIT_EXCEEDED."}}}}},"required":["error"]}}}},"404":{"description":"Resource not found, or not owned by the authenticating company.","content":{"application/json":{"schema":{"description":"Resource not found, or not owned by the authenticating company.","type":"object","properties":{"error":{"type":"string","description":"Human-readable error message (legacy alias for `title`)."},"title":{"type":"string","description":"Human-readable error message (RFC 9457)."},"status":{"type":"integer","description":"HTTP status code (RFC 9457)."},"statusCode":{"type":"integer","description":"HTTP status code (legacy alias for `status`)."},"type":{"type":"string","format":"uri","description":"URI pointing to the docs section for this error code (RFC 9457)."},"code":{"type":"string","description":"Machine-readable error code (stable identifier — see https://docs.billetsystems.com/errors)."},"request_id":{"type":"string","description":"Unique request identifier for support correlation."},"required_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the minimum tier needed to perform the operation."},"current_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the caller's current plan tier."},"errors":{"type":"array","description":"Per-field validation errors. Only present on 400 / 422 validation failures.","items":{"type":"object","properties":{"field":{"type":"string","description":"Dotted path of the failing field (e.g. `line_items.0.sku`)."},"message":{"type":"string","description":"Static, input-free description of the failure."},"code":{"type":"string","description":"Fixed-vocabulary field code — one of REQUIRED / INVALID_FORMAT / TOO_LONG / TOO_SHORT / TOO_BIG / TOO_SMALL / NOT_UNIQUE / INVALID_VALUE / TIER_LIMIT_EXCEEDED."}}}}},"required":["error"]}}}}}}},"/api/v1/drivers":{"get":{"summary":"List drivers","tags":["Drivers"],"description":"Returns every active salesperson / driver / can-deliver user in the authenticating company. Use the `id` from this list as the `driver_id` on POST /tickets or PUT /tickets/:id/assign. Not paginated — Billet companies rarely have more than ~50 drivers.","responses":{"200":{"description":"All active drivers.","content":{"application/json":{"schema":{"description":"All active drivers.","type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string","example":"Reed Gordon"},"code":{"type":"string","example":"D1"},"email":{"type":["null","string"],"format":"email"},"phone":{"type":["null","string"],"example":"+15551234567"},"role":{"type":"string","enum":["driver","salesperson","office","admin","manager"]},"position":{"type":["null","string"]}}}}}}}}},"401":{"description":"Missing, invalid, or deactivated API key.","content":{"application/json":{"schema":{"description":"Missing, invalid, or deactivated API key.","type":"object","properties":{"error":{"type":"string","description":"Human-readable error message (legacy alias for `title`)."},"title":{"type":"string","description":"Human-readable error message (RFC 9457)."},"status":{"type":"integer","description":"HTTP status code (RFC 9457)."},"statusCode":{"type":"integer","description":"HTTP status code (legacy alias for `status`)."},"type":{"type":"string","format":"uri","description":"URI pointing to the docs section for this error code (RFC 9457)."},"code":{"type":"string","description":"Machine-readable error code (stable identifier — see https://docs.billetsystems.com/errors)."},"request_id":{"type":"string","description":"Unique request identifier for support correlation."},"required_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the minimum tier needed to perform the operation."},"current_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the caller's current plan tier."},"errors":{"type":"array","description":"Per-field validation errors. Only present on 400 / 422 validation failures.","items":{"type":"object","properties":{"field":{"type":"string","description":"Dotted path of the failing field (e.g. `line_items.0.sku`)."},"message":{"type":"string","description":"Static, input-free description of the failure."},"code":{"type":"string","description":"Fixed-vocabulary field code — one of REQUIRED / INVALID_FORMAT / TOO_LONG / TOO_SHORT / TOO_BIG / TOO_SMALL / NOT_UNIQUE / INVALID_VALUE / TIER_LIMIT_EXCEEDED."}}}}},"required":["error"]}}}}}}},"/api/v1/branches":{"get":{"summary":"List branches","tags":["Branches"],"description":"Returns every branch (physical location) the authenticating company has configured. Solo-location companies will see a single \"Main\" branch created automatically at signup. Use the branch `id` as `branch_id` on POST /tickets to route a ticket to a specific location.","responses":{"200":{"description":"All branches.","content":{"application/json":{"schema":{"description":"All branches.","type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string","example":"Vicksburg"},"address_line1":{"type":["null","string"]},"city":{"type":["null","string"]},"state":{"type":["null","string"]},"zip":{"type":["null","string"]}}}}}}}}},"401":{"description":"Missing, invalid, or deactivated API key.","content":{"application/json":{"schema":{"description":"Missing, invalid, or deactivated API key.","type":"object","properties":{"error":{"type":"string","description":"Human-readable error message (legacy alias for `title`)."},"title":{"type":"string","description":"Human-readable error message (RFC 9457)."},"status":{"type":"integer","description":"HTTP status code (RFC 9457)."},"statusCode":{"type":"integer","description":"HTTP status code (legacy alias for `status`)."},"type":{"type":"string","format":"uri","description":"URI pointing to the docs section for this error code (RFC 9457)."},"code":{"type":"string","description":"Machine-readable error code (stable identifier — see https://docs.billetsystems.com/errors)."},"request_id":{"type":"string","description":"Unique request identifier for support correlation."},"required_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the minimum tier needed to perform the operation."},"current_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the caller's current plan tier."},"errors":{"type":"array","description":"Per-field validation errors. Only present on 400 / 422 validation failures.","items":{"type":"object","properties":{"field":{"type":"string","description":"Dotted path of the failing field (e.g. `line_items.0.sku`)."},"message":{"type":"string","description":"Static, input-free description of the failure."},"code":{"type":"string","description":"Fixed-vocabulary field code — one of REQUIRED / INVALID_FORMAT / TOO_LONG / TOO_SHORT / TOO_BIG / TOO_SMALL / NOT_UNIQUE / INVALID_VALUE / TIER_LIMIT_EXCEEDED."}}}}},"required":["error"]}}}}}}},"/api/v1/tickets/{id}/pdf":{"get":{"summary":"Download ticket PDF","tags":["Tickets"],"description":"Streams the rendered ticket PDF (signature block, GPS, photos, per-company branding). Returns `application/pdf` with `Content-Disposition: attachment`. Works on any ticket status — signed tickets include the full POD layout, unsigned tickets show the ticket header with empty signature lines.","parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"PDF binary.","content":{"application/pdf":{"schema":{"type":"string","format":"binary"}}}},"401":{"description":"Missing, invalid, or deactivated API key.","content":{"application/pdf":{"schema":{"description":"Missing, invalid, or deactivated API key.","type":"object","properties":{"error":{"type":"string","description":"Human-readable error message (legacy alias for `title`)."},"title":{"type":"string","description":"Human-readable error message (RFC 9457)."},"status":{"type":"integer","description":"HTTP status code (RFC 9457)."},"statusCode":{"type":"integer","description":"HTTP status code (legacy alias for `status`)."},"type":{"type":"string","format":"uri","description":"URI pointing to the docs section for this error code (RFC 9457)."},"code":{"type":"string","description":"Machine-readable error code (stable identifier — see https://docs.billetsystems.com/errors)."},"request_id":{"type":"string","description":"Unique request identifier for support correlation."},"required_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the minimum tier needed to perform the operation."},"current_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the caller's current plan tier."},"errors":{"type":"array","description":"Per-field validation errors. Only present on 400 / 422 validation failures.","items":{"type":"object","properties":{"field":{"type":"string","description":"Dotted path of the failing field (e.g. `line_items.0.sku`)."},"message":{"type":"string","description":"Static, input-free description of the failure."},"code":{"type":"string","description":"Fixed-vocabulary field code — one of REQUIRED / INVALID_FORMAT / TOO_LONG / TOO_SHORT / TOO_BIG / TOO_SMALL / NOT_UNIQUE / INVALID_VALUE / TIER_LIMIT_EXCEEDED."}}}}},"required":["error"]}}}},"404":{"description":"Resource not found, or not owned by the authenticating company.","content":{"application/pdf":{"schema":{"description":"Resource not found, or not owned by the authenticating company.","type":"object","properties":{"error":{"type":"string","description":"Human-readable error message (legacy alias for `title`)."},"title":{"type":"string","description":"Human-readable error message (RFC 9457)."},"status":{"type":"integer","description":"HTTP status code (RFC 9457)."},"statusCode":{"type":"integer","description":"HTTP status code (legacy alias for `status`)."},"type":{"type":"string","format":"uri","description":"URI pointing to the docs section for this error code (RFC 9457)."},"code":{"type":"string","description":"Machine-readable error code (stable identifier — see https://docs.billetsystems.com/errors)."},"request_id":{"type":"string","description":"Unique request identifier for support correlation."},"required_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the minimum tier needed to perform the operation."},"current_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the caller's current plan tier."},"errors":{"type":"array","description":"Per-field validation errors. Only present on 400 / 422 validation failures.","items":{"type":"object","properties":{"field":{"type":"string","description":"Dotted path of the failing field (e.g. `line_items.0.sku`)."},"message":{"type":"string","description":"Static, input-free description of the failure."},"code":{"type":"string","description":"Fixed-vocabulary field code — one of REQUIRED / INVALID_FORMAT / TOO_LONG / TOO_SHORT / TOO_BIG / TOO_SMALL / NOT_UNIQUE / INVALID_VALUE / TIER_LIMIT_EXCEEDED."}}}}},"required":["error"]}}}},"500":{"description":"PDF generation failed (rare — the PDF service is degraded).","content":{"application/pdf":{"schema":{"description":"PDF generation failed (rare — the PDF service is degraded).","type":"object","properties":{"error":{"type":"string","description":"Human-readable error message (legacy alias for `title`)."},"title":{"type":"string","description":"Human-readable error message (RFC 9457)."},"status":{"type":"integer","description":"HTTP status code (RFC 9457)."},"statusCode":{"type":"integer","description":"HTTP status code (legacy alias for `status`)."},"type":{"type":"string","format":"uri","description":"URI pointing to the docs section for this error code (RFC 9457)."},"code":{"type":"string","description":"Machine-readable error code (stable identifier — see https://docs.billetsystems.com/errors)."},"request_id":{"type":"string","description":"Unique request identifier for support correlation."},"required_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the minimum tier needed to perform the operation."},"current_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the caller's current plan tier."},"errors":{"type":"array","description":"Per-field validation errors. Only present on 400 / 422 validation failures.","items":{"type":"object","properties":{"field":{"type":"string","description":"Dotted path of the failing field (e.g. `line_items.0.sku`)."},"message":{"type":"string","description":"Static, input-free description of the failure."},"code":{"type":"string","description":"Fixed-vocabulary field code — one of REQUIRED / INVALID_FORMAT / TOO_LONG / TOO_SHORT / TOO_BIG / TOO_SMALL / NOT_UNIQUE / INVALID_VALUE / TIER_LIMIT_EXCEEDED."}}}}},"required":["error"]}}}}}}},"/api/v1/customers":{"get":{"summary":"List customers","tags":["Customers"],"description":"Returns a paginated list of customers. Optionally search by name / customer number, or exact-match on customer_number to check if a customer already exists before POSTing.","parameters":[{"schema":{"type":"integer","minimum":1,"default":1},"in":"query","name":"page","required":false},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":50},"in":"query","name":"per_page","required":false},{"schema":{"type":"string"},"in":"query","name":"search","required":false,"description":"Partial match on name or customer_number (case-insensitive)."},{"schema":{"type":"string"},"in":"query","name":"customer_number","required":false,"description":"Exact match on customer_number. Idempotency check before POST /customers."}],"responses":{"200":{"description":"Page of customers.","content":{"application/json":{"schema":{"description":"Page of customers.","type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"customer_number":{"type":"string","example":"15-0014125"},"name":{"type":"string","example":"Acme Plumbing Supply"},"contact_name":{"type":["null","string"],"example":"Bob Smith"},"email":{"type":["null","string"],"format":"email"},"phone":{"type":["null","string"],"example":"+15551234567"},"address_line1":{"type":["null","string"],"example":"1420 Main St"},"city":{"type":["null","string"],"example":"Dallas"},"state":{"type":["null","string"],"example":"TX"},"zip":{"type":["null","string"],"example":"75201"}}}},"meta":{"type":"object","description":"Pagination envelope. All v1 list endpoints return the same shape — page numbers start at 1, per_page defaults to 50 and caps at 100.","properties":{"page":{"type":"integer","example":1},"per_page":{"type":"integer","example":50},"total":{"type":"integer","example":247},"total_pages":{"type":"integer","example":5}}}}}}}},"401":{"description":"Missing, invalid, or deactivated API key.","content":{"application/json":{"schema":{"description":"Missing, invalid, or deactivated API key.","type":"object","properties":{"error":{"type":"string","description":"Human-readable error message (legacy alias for `title`)."},"title":{"type":"string","description":"Human-readable error message (RFC 9457)."},"status":{"type":"integer","description":"HTTP status code (RFC 9457)."},"statusCode":{"type":"integer","description":"HTTP status code (legacy alias for `status`)."},"type":{"type":"string","format":"uri","description":"URI pointing to the docs section for this error code (RFC 9457)."},"code":{"type":"string","description":"Machine-readable error code (stable identifier — see https://docs.billetsystems.com/errors)."},"request_id":{"type":"string","description":"Unique request identifier for support correlation."},"required_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the minimum tier needed to perform the operation."},"current_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the caller's current plan tier."},"errors":{"type":"array","description":"Per-field validation errors. Only present on 400 / 422 validation failures.","items":{"type":"object","properties":{"field":{"type":"string","description":"Dotted path of the failing field (e.g. `line_items.0.sku`)."},"message":{"type":"string","description":"Static, input-free description of the failure."},"code":{"type":"string","description":"Fixed-vocabulary field code — one of REQUIRED / INVALID_FORMAT / TOO_LONG / TOO_SHORT / TOO_BIG / TOO_SMALL / NOT_UNIQUE / INVALID_VALUE / TIER_LIMIT_EXCEEDED."}}}}},"required":["error"]}}}}}},"post":{"summary":"Create or update a customer","tags":["Customers"],"description":"Upserts a customer keyed on `customer_number`. If a customer with the same `customer_number` already exists, their fields are updated in place and a `customer.updated` webhook fires. Otherwise a new customer is created and a `customer.created` webhook fires. Omit `customer_number` to force-create with an auto-generated `API-<timestamp>` number.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name"],"additionalProperties":false,"properties":{"name":{"type":"string","minLength":1,"maxLength":200},"customer_number":{"type":"string","maxLength":100},"contact_name":{"type":"string","maxLength":200},"email":{"type":"string","maxLength":254},"phone":{"type":"string","maxLength":30},"address_line1":{"type":"string","maxLength":200},"city":{"type":"string","maxLength":100},"state":{"type":"string","maxLength":100},"zip":{"type":"string","maxLength":20}}}}}},"responses":{"201":{"description":"Customer created or updated.","content":{"application/json":{"schema":{"description":"Customer created or updated.","type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"customer_number":{"type":"string","example":"15-0014125"},"name":{"type":"string","example":"Acme Plumbing Supply"},"contact_name":{"type":["null","string"],"example":"Bob Smith"},"email":{"type":["null","string"],"format":"email"},"phone":{"type":["null","string"],"example":"+15551234567"},"address_line1":{"type":["null","string"],"example":"1420 Main St"},"city":{"type":["null","string"],"example":"Dallas"},"state":{"type":["null","string"],"example":"TX"},"zip":{"type":["null","string"],"example":"75201"}}}}}}}},"400":{"description":"Malformed request — bad JSON, wrong type, missing required field, or pattern mismatch. `errors[]` enumerates every failing field.","content":{"application/json":{"schema":{"description":"Malformed request — bad JSON, wrong type, missing required field, or pattern mismatch. `errors[]` enumerates every failing field.","type":"object","properties":{"error":{"type":"string","description":"Human-readable error message (legacy alias for `title`)."},"title":{"type":"string","description":"Human-readable error message (RFC 9457)."},"status":{"type":"integer","description":"HTTP status code (RFC 9457)."},"statusCode":{"type":"integer","description":"HTTP status code (legacy alias for `status`)."},"type":{"type":"string","format":"uri","description":"URI pointing to the docs section for this error code (RFC 9457)."},"code":{"type":"string","description":"Machine-readable error code (stable identifier — see https://docs.billetsystems.com/errors)."},"request_id":{"type":"string","description":"Unique request identifier for support correlation."},"required_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the minimum tier needed to perform the operation."},"current_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the caller's current plan tier."},"errors":{"type":"array","description":"Per-field validation errors. Only present on 400 / 422 validation failures.","items":{"type":"object","properties":{"field":{"type":"string","description":"Dotted path of the failing field (e.g. `line_items.0.sku`)."},"message":{"type":"string","description":"Static, input-free description of the failure."},"code":{"type":"string","description":"Fixed-vocabulary field code — one of REQUIRED / INVALID_FORMAT / TOO_LONG / TOO_SHORT / TOO_BIG / TOO_SMALL / NOT_UNIQUE / INVALID_VALUE / TIER_LIMIT_EXCEEDED."}}}}},"required":["error"]}}}},"401":{"description":"Missing, invalid, or deactivated API key.","content":{"application/json":{"schema":{"description":"Missing, invalid, or deactivated API key.","type":"object","properties":{"error":{"type":"string","description":"Human-readable error message (legacy alias for `title`)."},"title":{"type":"string","description":"Human-readable error message (RFC 9457)."},"status":{"type":"integer","description":"HTTP status code (RFC 9457)."},"statusCode":{"type":"integer","description":"HTTP status code (legacy alias for `status`)."},"type":{"type":"string","format":"uri","description":"URI pointing to the docs section for this error code (RFC 9457)."},"code":{"type":"string","description":"Machine-readable error code (stable identifier — see https://docs.billetsystems.com/errors)."},"request_id":{"type":"string","description":"Unique request identifier for support correlation."},"required_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the minimum tier needed to perform the operation."},"current_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the caller's current plan tier."},"errors":{"type":"array","description":"Per-field validation errors. Only present on 400 / 422 validation failures.","items":{"type":"object","properties":{"field":{"type":"string","description":"Dotted path of the failing field (e.g. `line_items.0.sku`)."},"message":{"type":"string","description":"Static, input-free description of the failure."},"code":{"type":"string","description":"Fixed-vocabulary field code — one of REQUIRED / INVALID_FORMAT / TOO_LONG / TOO_SHORT / TOO_BIG / TOO_SMALL / NOT_UNIQUE / INVALID_VALUE / TIER_LIMIT_EXCEEDED."}}}}},"required":["error"]}}}}}}},"/api/v1/products":{"get":{"summary":"List products","tags":["Products"],"description":"Returns a paginated list of products. Available on every tier (even Essentials can read). Products are synced from QuickBooks / Xero / FreshBooks when an accounting integration is connected, or created manually via POST /products. Use the `updated_since` filter for incremental sync.","parameters":[{"schema":{"type":"integer","minimum":1,"default":1},"in":"query","name":"page","required":false},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":50},"in":"query","name":"per_page","required":false},{"schema":{"type":"string"},"in":"query","name":"sku","required":false,"description":"Exact match on SKU."},{"schema":{"type":"string"},"in":"query","name":"barcode","required":false,"description":"Exact match on barcode / UPC."},{"schema":{"type":"string","format":"date-time"},"in":"query","name":"updated_since","required":false,"description":"Only products updated on or after this timestamp. Use for incremental sync."},{"schema":{"type":"string","enum":["true","false"]},"in":"query","name":"is_active","required":false,"description":"Only active (is_sold=true) or inactive products."},{"schema":{"type":"string"},"in":"query","name":"search","required":false,"description":"Partial match on name, sku, or description (case-insensitive)."}],"responses":{"200":{"description":"Page of products.","content":{"application/json":{"schema":{"description":"Page of products.","type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string","example":"1/2 inch Copper Fitting"},"sku":{"type":["null","string"],"example":"CF-050"},"barcode":{"type":["null","string"],"example":"012345678905"},"description":{"type":["null","string"]},"unit_price":{"type":["null","number"],"example":4.5},"cost_price":{"type":["null","number"],"example":2.1},"tax_rate":{"type":["null","number"],"description":"Decimal fraction, e.g. 0.0825 for 8.25%.","example":0.0825},"quantity_on_hand":{"type":["null","number"]},"unit":{"type":["null","string"],"example":"each"},"is_tracked_inventory":{"type":"boolean"},"is_sold":{"type":"boolean"},"sync_source":{"type":["null","string"],"enum":[null,"quickbooks","xero","freshbooks","manual"]},"external_id":{"type":["null","string"]},"custom_fields":{"type":"object","additionalProperties":true},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}}},"meta":{"type":"object","description":"Pagination envelope. All v1 list endpoints return the same shape — page numbers start at 1, per_page defaults to 50 and caps at 100.","properties":{"page":{"type":"integer","example":1},"per_page":{"type":"integer","example":50},"total":{"type":"integer","example":247},"total_pages":{"type":"integer","example":5}}}}}}}},"401":{"description":"Missing, invalid, or deactivated API key.","content":{"application/json":{"schema":{"description":"Missing, invalid, or deactivated API key.","type":"object","properties":{"error":{"type":"string","description":"Human-readable error message (legacy alias for `title`)."},"title":{"type":"string","description":"Human-readable error message (RFC 9457)."},"status":{"type":"integer","description":"HTTP status code (RFC 9457)."},"statusCode":{"type":"integer","description":"HTTP status code (legacy alias for `status`)."},"type":{"type":"string","format":"uri","description":"URI pointing to the docs section for this error code (RFC 9457)."},"code":{"type":"string","description":"Machine-readable error code (stable identifier — see https://docs.billetsystems.com/errors)."},"request_id":{"type":"string","description":"Unique request identifier for support correlation."},"required_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the minimum tier needed to perform the operation."},"current_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the caller's current plan tier."},"errors":{"type":"array","description":"Per-field validation errors. Only present on 400 / 422 validation failures.","items":{"type":"object","properties":{"field":{"type":"string","description":"Dotted path of the failing field (e.g. `line_items.0.sku`)."},"message":{"type":"string","description":"Static, input-free description of the failure."},"code":{"type":"string","description":"Fixed-vocabulary field code — one of REQUIRED / INVALID_FORMAT / TOO_LONG / TOO_SHORT / TOO_BIG / TOO_SMALL / NOT_UNIQUE / INVALID_VALUE / TIER_LIMIT_EXCEEDED."}}}}},"required":["error"]}}}}}},"post":{"summary":"Create or update a product (Standard+ tier)","tags":["Products"],"description":"Upserts a product keyed on `sku`. If `sku` matches an existing product, that row is updated and a `product.updated` webhook fires. Otherwise a new product is created with `product.created`. Omitting `sku` always inserts a new row. **Requires Standard or Professional plan** — Essentials gets a 403 with `code: TIER_REQUIRED`.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name"],"additionalProperties":false,"properties":{"name":{"type":"string","minLength":1,"maxLength":300},"sku":{"type":"string","maxLength":100},"barcode":{"type":"string","maxLength":64},"description":{"type":"string","maxLength":2000},"unit_price":{"type":"number"},"cost_price":{"type":"number"},"tax_rate":{"type":"number","minimum":0,"maximum":1},"quantity_on_hand":{"type":"number"},"unit":{"type":"string","maxLength":20},"is_tracked_inventory":{"type":"boolean"},"is_sold":{"type":"boolean"},"custom_fields":{"type":"object","maxProperties":50}}}}}},"responses":{"200":{"description":"Product updated (upsert hit an existing SKU).","content":{"application/json":{"schema":{"description":"Product updated (upsert hit an existing SKU).","type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string","example":"1/2 inch Copper Fitting"},"sku":{"type":["null","string"],"example":"CF-050"},"barcode":{"type":["null","string"],"example":"012345678905"},"description":{"type":["null","string"]},"unit_price":{"type":["null","number"],"example":4.5},"cost_price":{"type":["null","number"],"example":2.1},"tax_rate":{"type":["null","number"],"description":"Decimal fraction, e.g. 0.0825 for 8.25%.","example":0.0825},"quantity_on_hand":{"type":["null","number"]},"unit":{"type":["null","string"],"example":"each"},"is_tracked_inventory":{"type":"boolean"},"is_sold":{"type":"boolean"},"sync_source":{"type":["null","string"],"enum":[null,"quickbooks","xero","freshbooks","manual"]},"external_id":{"type":["null","string"]},"custom_fields":{"type":"object","additionalProperties":true},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}}}}}}},"201":{"description":"Product created (new row).","content":{"application/json":{"schema":{"description":"Product created (new row).","type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string","example":"1/2 inch Copper Fitting"},"sku":{"type":["null","string"],"example":"CF-050"},"barcode":{"type":["null","string"],"example":"012345678905"},"description":{"type":["null","string"]},"unit_price":{"type":["null","number"],"example":4.5},"cost_price":{"type":["null","number"],"example":2.1},"tax_rate":{"type":["null","number"],"description":"Decimal fraction, e.g. 0.0825 for 8.25%.","example":0.0825},"quantity_on_hand":{"type":["null","number"]},"unit":{"type":["null","string"],"example":"each"},"is_tracked_inventory":{"type":"boolean"},"is_sold":{"type":"boolean"},"sync_source":{"type":["null","string"],"enum":[null,"quickbooks","xero","freshbooks","manual"]},"external_id":{"type":["null","string"]},"custom_fields":{"type":"object","additionalProperties":true},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}}}}}}},"400":{"description":"Malformed request — bad JSON, wrong type, missing required field, or pattern mismatch. `errors[]` enumerates every failing field.","content":{"application/json":{"schema":{"description":"Malformed request — bad JSON, wrong type, missing required field, or pattern mismatch. `errors[]` enumerates every failing field.","type":"object","properties":{"error":{"type":"string","description":"Human-readable error message (legacy alias for `title`)."},"title":{"type":"string","description":"Human-readable error message (RFC 9457)."},"status":{"type":"integer","description":"HTTP status code (RFC 9457)."},"statusCode":{"type":"integer","description":"HTTP status code (legacy alias for `status`)."},"type":{"type":"string","format":"uri","description":"URI pointing to the docs section for this error code (RFC 9457)."},"code":{"type":"string","description":"Machine-readable error code (stable identifier — see https://docs.billetsystems.com/errors)."},"request_id":{"type":"string","description":"Unique request identifier for support correlation."},"required_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the minimum tier needed to perform the operation."},"current_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the caller's current plan tier."},"errors":{"type":"array","description":"Per-field validation errors. Only present on 400 / 422 validation failures.","items":{"type":"object","properties":{"field":{"type":"string","description":"Dotted path of the failing field (e.g. `line_items.0.sku`)."},"message":{"type":"string","description":"Static, input-free description of the failure."},"code":{"type":"string","description":"Fixed-vocabulary field code — one of REQUIRED / INVALID_FORMAT / TOO_LONG / TOO_SHORT / TOO_BIG / TOO_SMALL / NOT_UNIQUE / INVALID_VALUE / TIER_LIMIT_EXCEEDED."}}}}},"required":["error"]}}}},"401":{"description":"Missing, invalid, or deactivated API key.","content":{"application/json":{"schema":{"description":"Missing, invalid, or deactivated API key.","type":"object","properties":{"error":{"type":"string","description":"Human-readable error message (legacy alias for `title`)."},"title":{"type":"string","description":"Human-readable error message (RFC 9457)."},"status":{"type":"integer","description":"HTTP status code (RFC 9457)."},"statusCode":{"type":"integer","description":"HTTP status code (legacy alias for `status`)."},"type":{"type":"string","format":"uri","description":"URI pointing to the docs section for this error code (RFC 9457)."},"code":{"type":"string","description":"Machine-readable error code (stable identifier — see https://docs.billetsystems.com/errors)."},"request_id":{"type":"string","description":"Unique request identifier for support correlation."},"required_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the minimum tier needed to perform the operation."},"current_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the caller's current plan tier."},"errors":{"type":"array","description":"Per-field validation errors. Only present on 400 / 422 validation failures.","items":{"type":"object","properties":{"field":{"type":"string","description":"Dotted path of the failing field (e.g. `line_items.0.sku`)."},"message":{"type":"string","description":"Static, input-free description of the failure."},"code":{"type":"string","description":"Fixed-vocabulary field code — one of REQUIRED / INVALID_FORMAT / TOO_LONG / TOO_SHORT / TOO_BIG / TOO_SMALL / NOT_UNIQUE / INVALID_VALUE / TIER_LIMIT_EXCEEDED."}}}}},"required":["error"]}}}},"403":{"description":"Caller is authenticated but the current plan tier does not allow this operation (see `code: TIER_REQUIRED`).","content":{"application/json":{"schema":{"description":"Caller is authenticated but the current plan tier does not allow this operation (see `code: TIER_REQUIRED`).","type":"object","properties":{"error":{"type":"string","description":"Human-readable error message (legacy alias for `title`)."},"title":{"type":"string","description":"Human-readable error message (RFC 9457)."},"status":{"type":"integer","description":"HTTP status code (RFC 9457)."},"statusCode":{"type":"integer","description":"HTTP status code (legacy alias for `status`)."},"type":{"type":"string","format":"uri","description":"URI pointing to the docs section for this error code (RFC 9457)."},"code":{"type":"string","description":"Machine-readable error code (stable identifier — see https://docs.billetsystems.com/errors)."},"request_id":{"type":"string","description":"Unique request identifier for support correlation."},"required_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the minimum tier needed to perform the operation."},"current_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the caller's current plan tier."},"errors":{"type":"array","description":"Per-field validation errors. Only present on 400 / 422 validation failures.","items":{"type":"object","properties":{"field":{"type":"string","description":"Dotted path of the failing field (e.g. `line_items.0.sku`)."},"message":{"type":"string","description":"Static, input-free description of the failure."},"code":{"type":"string","description":"Fixed-vocabulary field code — one of REQUIRED / INVALID_FORMAT / TOO_LONG / TOO_SHORT / TOO_BIG / TOO_SMALL / NOT_UNIQUE / INVALID_VALUE / TIER_LIMIT_EXCEEDED."}}}}},"required":["error"]}}}}}}},"/api/v1/products/{id}":{"get":{"summary":"Get a product by id","tags":["Products"],"description":"Returns the full product record. Available on every tier.","parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Full product record.","content":{"application/json":{"schema":{"description":"Full product record.","type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string","example":"1/2 inch Copper Fitting"},"sku":{"type":["null","string"],"example":"CF-050"},"barcode":{"type":["null","string"],"example":"012345678905"},"description":{"type":["null","string"]},"unit_price":{"type":["null","number"],"example":4.5},"cost_price":{"type":["null","number"],"example":2.1},"tax_rate":{"type":["null","number"],"description":"Decimal fraction, e.g. 0.0825 for 8.25%.","example":0.0825},"quantity_on_hand":{"type":["null","number"]},"unit":{"type":["null","string"],"example":"each"},"is_tracked_inventory":{"type":"boolean"},"is_sold":{"type":"boolean"},"sync_source":{"type":["null","string"],"enum":[null,"quickbooks","xero","freshbooks","manual"]},"external_id":{"type":["null","string"]},"custom_fields":{"type":"object","additionalProperties":true},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}}}}}}},"401":{"description":"Missing, invalid, or deactivated API key.","content":{"application/json":{"schema":{"description":"Missing, invalid, or deactivated API key.","type":"object","properties":{"error":{"type":"string","description":"Human-readable error message (legacy alias for `title`)."},"title":{"type":"string","description":"Human-readable error message (RFC 9457)."},"status":{"type":"integer","description":"HTTP status code (RFC 9457)."},"statusCode":{"type":"integer","description":"HTTP status code (legacy alias for `status`)."},"type":{"type":"string","format":"uri","description":"URI pointing to the docs section for this error code (RFC 9457)."},"code":{"type":"string","description":"Machine-readable error code (stable identifier — see https://docs.billetsystems.com/errors)."},"request_id":{"type":"string","description":"Unique request identifier for support correlation."},"required_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the minimum tier needed to perform the operation."},"current_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the caller's current plan tier."},"errors":{"type":"array","description":"Per-field validation errors. Only present on 400 / 422 validation failures.","items":{"type":"object","properties":{"field":{"type":"string","description":"Dotted path of the failing field (e.g. `line_items.0.sku`)."},"message":{"type":"string","description":"Static, input-free description of the failure."},"code":{"type":"string","description":"Fixed-vocabulary field code — one of REQUIRED / INVALID_FORMAT / TOO_LONG / TOO_SHORT / TOO_BIG / TOO_SMALL / NOT_UNIQUE / INVALID_VALUE / TIER_LIMIT_EXCEEDED."}}}}},"required":["error"]}}}},"404":{"description":"Resource not found, or not owned by the authenticating company.","content":{"application/json":{"schema":{"description":"Resource not found, or not owned by the authenticating company.","type":"object","properties":{"error":{"type":"string","description":"Human-readable error message (legacy alias for `title`)."},"title":{"type":"string","description":"Human-readable error message (RFC 9457)."},"status":{"type":"integer","description":"HTTP status code (RFC 9457)."},"statusCode":{"type":"integer","description":"HTTP status code (legacy alias for `status`)."},"type":{"type":"string","format":"uri","description":"URI pointing to the docs section for this error code (RFC 9457)."},"code":{"type":"string","description":"Machine-readable error code (stable identifier — see https://docs.billetsystems.com/errors)."},"request_id":{"type":"string","description":"Unique request identifier for support correlation."},"required_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the minimum tier needed to perform the operation."},"current_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the caller's current plan tier."},"errors":{"type":"array","description":"Per-field validation errors. Only present on 400 / 422 validation failures.","items":{"type":"object","properties":{"field":{"type":"string","description":"Dotted path of the failing field (e.g. `line_items.0.sku`)."},"message":{"type":"string","description":"Static, input-free description of the failure."},"code":{"type":"string","description":"Fixed-vocabulary field code — one of REQUIRED / INVALID_FORMAT / TOO_LONG / TOO_SHORT / TOO_BIG / TOO_SMALL / NOT_UNIQUE / INVALID_VALUE / TIER_LIMIT_EXCEEDED."}}}}},"required":["error"]}}}}}},"put":{"summary":"Update a product (Standard+ tier)","tags":["Products"],"description":"Partial update — only the fields you include are touched. Fires `product.updated`. **Requires Standard or Professional plan.**","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"name":{"type":"string","minLength":1,"maxLength":300},"sku":{"type":"string","maxLength":100},"barcode":{"type":"string","maxLength":64},"description":{"type":"string","maxLength":2000},"unit_price":{"type":"number"},"cost_price":{"type":"number"},"tax_rate":{"type":"number","minimum":0,"maximum":1},"quantity_on_hand":{"type":"number"},"unit":{"type":"string","maxLength":20},"is_tracked_inventory":{"type":"boolean"},"is_sold":{"type":"boolean"},"custom_fields":{"type":"object","maxProperties":50}}}}}},"parameters":[{"schema":{"type":"string","format":"uuid","pattern":"^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Product updated.","content":{"application/json":{"schema":{"description":"Product updated.","type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string","example":"1/2 inch Copper Fitting"},"sku":{"type":["null","string"],"example":"CF-050"},"barcode":{"type":["null","string"],"example":"012345678905"},"description":{"type":["null","string"]},"unit_price":{"type":["null","number"],"example":4.5},"cost_price":{"type":["null","number"],"example":2.1},"tax_rate":{"type":["null","number"],"description":"Decimal fraction, e.g. 0.0825 for 8.25%.","example":0.0825},"quantity_on_hand":{"type":["null","number"]},"unit":{"type":["null","string"],"example":"each"},"is_tracked_inventory":{"type":"boolean"},"is_sold":{"type":"boolean"},"sync_source":{"type":["null","string"],"enum":[null,"quickbooks","xero","freshbooks","manual"]},"external_id":{"type":["null","string"]},"custom_fields":{"type":"object","additionalProperties":true},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}}}}}}},"400":{"description":"Malformed request — bad JSON, wrong type, missing required field, or pattern mismatch. `errors[]` enumerates every failing field.","content":{"application/json":{"schema":{"description":"Malformed request — bad JSON, wrong type, missing required field, or pattern mismatch. `errors[]` enumerates every failing field.","type":"object","properties":{"error":{"type":"string","description":"Human-readable error message (legacy alias for `title`)."},"title":{"type":"string","description":"Human-readable error message (RFC 9457)."},"status":{"type":"integer","description":"HTTP status code (RFC 9457)."},"statusCode":{"type":"integer","description":"HTTP status code (legacy alias for `status`)."},"type":{"type":"string","format":"uri","description":"URI pointing to the docs section for this error code (RFC 9457)."},"code":{"type":"string","description":"Machine-readable error code (stable identifier — see https://docs.billetsystems.com/errors)."},"request_id":{"type":"string","description":"Unique request identifier for support correlation."},"required_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the minimum tier needed to perform the operation."},"current_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the caller's current plan tier."},"errors":{"type":"array","description":"Per-field validation errors. Only present on 400 / 422 validation failures.","items":{"type":"object","properties":{"field":{"type":"string","description":"Dotted path of the failing field (e.g. `line_items.0.sku`)."},"message":{"type":"string","description":"Static, input-free description of the failure."},"code":{"type":"string","description":"Fixed-vocabulary field code — one of REQUIRED / INVALID_FORMAT / TOO_LONG / TOO_SHORT / TOO_BIG / TOO_SMALL / NOT_UNIQUE / INVALID_VALUE / TIER_LIMIT_EXCEEDED."}}}}},"required":["error"]}}}},"401":{"description":"Missing, invalid, or deactivated API key.","content":{"application/json":{"schema":{"description":"Missing, invalid, or deactivated API key.","type":"object","properties":{"error":{"type":"string","description":"Human-readable error message (legacy alias for `title`)."},"title":{"type":"string","description":"Human-readable error message (RFC 9457)."},"status":{"type":"integer","description":"HTTP status code (RFC 9457)."},"statusCode":{"type":"integer","description":"HTTP status code (legacy alias for `status`)."},"type":{"type":"string","format":"uri","description":"URI pointing to the docs section for this error code (RFC 9457)."},"code":{"type":"string","description":"Machine-readable error code (stable identifier — see https://docs.billetsystems.com/errors)."},"request_id":{"type":"string","description":"Unique request identifier for support correlation."},"required_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the minimum tier needed to perform the operation."},"current_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the caller's current plan tier."},"errors":{"type":"array","description":"Per-field validation errors. Only present on 400 / 422 validation failures.","items":{"type":"object","properties":{"field":{"type":"string","description":"Dotted path of the failing field (e.g. `line_items.0.sku`)."},"message":{"type":"string","description":"Static, input-free description of the failure."},"code":{"type":"string","description":"Fixed-vocabulary field code — one of REQUIRED / INVALID_FORMAT / TOO_LONG / TOO_SHORT / TOO_BIG / TOO_SMALL / NOT_UNIQUE / INVALID_VALUE / TIER_LIMIT_EXCEEDED."}}}}},"required":["error"]}}}},"403":{"description":"Caller is authenticated but the current plan tier does not allow this operation (see `code: TIER_REQUIRED`).","content":{"application/json":{"schema":{"description":"Caller is authenticated but the current plan tier does not allow this operation (see `code: TIER_REQUIRED`).","type":"object","properties":{"error":{"type":"string","description":"Human-readable error message (legacy alias for `title`)."},"title":{"type":"string","description":"Human-readable error message (RFC 9457)."},"status":{"type":"integer","description":"HTTP status code (RFC 9457)."},"statusCode":{"type":"integer","description":"HTTP status code (legacy alias for `status`)."},"type":{"type":"string","format":"uri","description":"URI pointing to the docs section for this error code (RFC 9457)."},"code":{"type":"string","description":"Machine-readable error code (stable identifier — see https://docs.billetsystems.com/errors)."},"request_id":{"type":"string","description":"Unique request identifier for support correlation."},"required_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the minimum tier needed to perform the operation."},"current_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the caller's current plan tier."},"errors":{"type":"array","description":"Per-field validation errors. Only present on 400 / 422 validation failures.","items":{"type":"object","properties":{"field":{"type":"string","description":"Dotted path of the failing field (e.g. `line_items.0.sku`)."},"message":{"type":"string","description":"Static, input-free description of the failure."},"code":{"type":"string","description":"Fixed-vocabulary field code — one of REQUIRED / INVALID_FORMAT / TOO_LONG / TOO_SHORT / TOO_BIG / TOO_SMALL / NOT_UNIQUE / INVALID_VALUE / TIER_LIMIT_EXCEEDED."}}}}},"required":["error"]}}}},"404":{"description":"Resource not found, or not owned by the authenticating company.","content":{"application/json":{"schema":{"description":"Resource not found, or not owned by the authenticating company.","type":"object","properties":{"error":{"type":"string","description":"Human-readable error message (legacy alias for `title`)."},"title":{"type":"string","description":"Human-readable error message (RFC 9457)."},"status":{"type":"integer","description":"HTTP status code (RFC 9457)."},"statusCode":{"type":"integer","description":"HTTP status code (legacy alias for `status`)."},"type":{"type":"string","format":"uri","description":"URI pointing to the docs section for this error code (RFC 9457)."},"code":{"type":"string","description":"Machine-readable error code (stable identifier — see https://docs.billetsystems.com/errors)."},"request_id":{"type":"string","description":"Unique request identifier for support correlation."},"required_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the minimum tier needed to perform the operation."},"current_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the caller's current plan tier."},"errors":{"type":"array","description":"Per-field validation errors. Only present on 400 / 422 validation failures.","items":{"type":"object","properties":{"field":{"type":"string","description":"Dotted path of the failing field (e.g. `line_items.0.sku`)."},"message":{"type":"string","description":"Static, input-free description of the failure."},"code":{"type":"string","description":"Fixed-vocabulary field code — one of REQUIRED / INVALID_FORMAT / TOO_LONG / TOO_SHORT / TOO_BIG / TOO_SMALL / NOT_UNIQUE / INVALID_VALUE / TIER_LIMIT_EXCEEDED."}}}}},"required":["error"]}}}},"422":{"description":"Request is well-formed but cannot be processed — e.g. a ticket cannot be edited in its current status, or an `Idempotency-Key` was reused with a different request body.","content":{"application/json":{"schema":{"description":"Request is well-formed but cannot be processed — e.g. a ticket cannot be edited in its current status, or an `Idempotency-Key` was reused with a different request body.","type":"object","properties":{"error":{"type":"string","description":"Human-readable error message (legacy alias for `title`)."},"title":{"type":"string","description":"Human-readable error message (RFC 9457)."},"status":{"type":"integer","description":"HTTP status code (RFC 9457)."},"statusCode":{"type":"integer","description":"HTTP status code (legacy alias for `status`)."},"type":{"type":"string","format":"uri","description":"URI pointing to the docs section for this error code (RFC 9457)."},"code":{"type":"string","description":"Machine-readable error code (stable identifier — see https://docs.billetsystems.com/errors)."},"request_id":{"type":"string","description":"Unique request identifier for support correlation."},"required_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the minimum tier needed to perform the operation."},"current_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the caller's current plan tier."},"errors":{"type":"array","description":"Per-field validation errors. Only present on 400 / 422 validation failures.","items":{"type":"object","properties":{"field":{"type":"string","description":"Dotted path of the failing field (e.g. `line_items.0.sku`)."},"message":{"type":"string","description":"Static, input-free description of the failure."},"code":{"type":"string","description":"Fixed-vocabulary field code — one of REQUIRED / INVALID_FORMAT / TOO_LONG / TOO_SHORT / TOO_BIG / TOO_SMALL / NOT_UNIQUE / INVALID_VALUE / TIER_LIMIT_EXCEEDED."}}}}},"required":["error"]}}}}}}},"/api/v1/webhooks":{"get":{"summary":"List webhook subscriptions","tags":["Webhooks"],"description":"Returns every webhook subscription registered for the authenticating company. Includes subscriptions created via the dashboard AND via the API (this endpoint). The response never includes the signing secret — secrets are shown only once, at creation time.","responses":{"200":{"description":"All webhook subscriptions.","content":{"application/json":{"schema":{"description":"All webhook subscriptions.","type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"url":{"type":"string","format":"uri","example":"https://example.com/webhooks/billet"},"events":{"type":"array","items":{"type":"string"},"example":["ticket.signed","ticket.paid"]},"is_active":{"type":"boolean"},"validation_status":{"type":"string","enum":["pending","validated","failed"]},"created_at":{"type":"string","format":"date-time"}}}}}}}}},"401":{"description":"Missing, invalid, or deactivated API key.","content":{"application/json":{"schema":{"description":"Missing, invalid, or deactivated API key.","type":"object","properties":{"error":{"type":"string","description":"Human-readable error message (legacy alias for `title`)."},"title":{"type":"string","description":"Human-readable error message (RFC 9457)."},"status":{"type":"integer","description":"HTTP status code (RFC 9457)."},"statusCode":{"type":"integer","description":"HTTP status code (legacy alias for `status`)."},"type":{"type":"string","format":"uri","description":"URI pointing to the docs section for this error code (RFC 9457)."},"code":{"type":"string","description":"Machine-readable error code (stable identifier — see https://docs.billetsystems.com/errors)."},"request_id":{"type":"string","description":"Unique request identifier for support correlation."},"required_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the minimum tier needed to perform the operation."},"current_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the caller's current plan tier."},"errors":{"type":"array","description":"Per-field validation errors. Only present on 400 / 422 validation failures.","items":{"type":"object","properties":{"field":{"type":"string","description":"Dotted path of the failing field (e.g. `line_items.0.sku`)."},"message":{"type":"string","description":"Static, input-free description of the failure."},"code":{"type":"string","description":"Fixed-vocabulary field code — one of REQUIRED / INVALID_FORMAT / TOO_LONG / TOO_SHORT / TOO_BIG / TOO_SMALL / NOT_UNIQUE / INVALID_VALUE / TIER_LIMIT_EXCEEDED."}}}}},"required":["error"]}}}}}},"post":{"summary":"Create a webhook subscription","tags":["Webhooks"],"description":"Registers a URL to receive signed JSON POSTs on the selected events. The response includes a `secret` (32 hex bytes) used to verify the HMAC signature on incoming events — **store it securely, it is only shown once**. Supports both Zapier-style `{target_url, event}` and native `{url, events[]}` payload shapes. Production URLs must use HTTPS. Supported events include ticket.created, ticket.signed, ticket.paid, ticket.rejected, customer.created, customer.updated, product.created, and more — see the Webhooks section for the full catalog.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","format":"uri","description":"The URL to POST events to. HTTPS required in production."},"target_url":{"type":"string","format":"uri","description":"Zapier-style alias for `url`. Use either, not both."},"events":{"type":"array","items":{"type":"string"},"description":"List of event names to subscribe to."},"event":{"type":"string","description":"Zapier-style single-event alias. Use either `event` or `events`."}}}}}},"responses":{"201":{"description":"Subscription created. Persist the `secret` field for HMAC verification.","content":{"application/json":{"schema":{"description":"Subscription created. Persist the `secret` field for HMAC verification.","type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"url":{"type":"string","format":"uri","example":"https://example.com/webhooks/billet"},"events":{"type":"array","items":{"type":"string"},"example":["ticket.signed","ticket.paid"]},"is_active":{"type":"boolean"},"validation_status":{"type":"string","enum":["pending","validated","failed"]},"created_at":{"type":"string","format":"date-time"},"secret":{"type":"string","description":"HMAC signing key. Shown once — store it now."}}}}}}}},"400":{"description":"Malformed request — bad JSON, wrong type, missing required field, or pattern mismatch. `errors[]` enumerates every failing field.","content":{"application/json":{"schema":{"description":"Malformed request — bad JSON, wrong type, missing required field, or pattern mismatch. `errors[]` enumerates every failing field.","type":"object","properties":{"error":{"type":"string","description":"Human-readable error message (legacy alias for `title`)."},"title":{"type":"string","description":"Human-readable error message (RFC 9457)."},"status":{"type":"integer","description":"HTTP status code (RFC 9457)."},"statusCode":{"type":"integer","description":"HTTP status code (legacy alias for `status`)."},"type":{"type":"string","format":"uri","description":"URI pointing to the docs section for this error code (RFC 9457)."},"code":{"type":"string","description":"Machine-readable error code (stable identifier — see https://docs.billetsystems.com/errors)."},"request_id":{"type":"string","description":"Unique request identifier for support correlation."},"required_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the minimum tier needed to perform the operation."},"current_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the caller's current plan tier."},"errors":{"type":"array","description":"Per-field validation errors. Only present on 400 / 422 validation failures.","items":{"type":"object","properties":{"field":{"type":"string","description":"Dotted path of the failing field (e.g. `line_items.0.sku`)."},"message":{"type":"string","description":"Static, input-free description of the failure."},"code":{"type":"string","description":"Fixed-vocabulary field code — one of REQUIRED / INVALID_FORMAT / TOO_LONG / TOO_SHORT / TOO_BIG / TOO_SMALL / NOT_UNIQUE / INVALID_VALUE / TIER_LIMIT_EXCEEDED."}}}}},"required":["error"]}}}},"401":{"description":"Missing, invalid, or deactivated API key.","content":{"application/json":{"schema":{"description":"Missing, invalid, or deactivated API key.","type":"object","properties":{"error":{"type":"string","description":"Human-readable error message (legacy alias for `title`)."},"title":{"type":"string","description":"Human-readable error message (RFC 9457)."},"status":{"type":"integer","description":"HTTP status code (RFC 9457)."},"statusCode":{"type":"integer","description":"HTTP status code (legacy alias for `status`)."},"type":{"type":"string","format":"uri","description":"URI pointing to the docs section for this error code (RFC 9457)."},"code":{"type":"string","description":"Machine-readable error code (stable identifier — see https://docs.billetsystems.com/errors)."},"request_id":{"type":"string","description":"Unique request identifier for support correlation."},"required_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the minimum tier needed to perform the operation."},"current_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the caller's current plan tier."},"errors":{"type":"array","description":"Per-field validation errors. Only present on 400 / 422 validation failures.","items":{"type":"object","properties":{"field":{"type":"string","description":"Dotted path of the failing field (e.g. `line_items.0.sku`)."},"message":{"type":"string","description":"Static, input-free description of the failure."},"code":{"type":"string","description":"Fixed-vocabulary field code — one of REQUIRED / INVALID_FORMAT / TOO_LONG / TOO_SHORT / TOO_BIG / TOO_SMALL / NOT_UNIQUE / INVALID_VALUE / TIER_LIMIT_EXCEEDED."}}}}},"required":["error"]}}}}}}},"/api/v1/webhooks/{id}":{"delete":{"summary":"Delete a webhook subscription","tags":["Webhooks"],"description":"Removes a webhook subscription. Pending / in-flight events already queued for this subscription are discarded. Idempotent — calling DELETE on an already-deleted id returns 404.","parameters":[{"schema":{"type":"string","format":"uuid"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Subscription deleted.","content":{"application/json":{"schema":{"description":"Subscription deleted.","type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"deleted":{"type":"boolean","example":true}}}}}}}},"401":{"description":"Missing, invalid, or deactivated API key.","content":{"application/json":{"schema":{"description":"Missing, invalid, or deactivated API key.","type":"object","properties":{"error":{"type":"string","description":"Human-readable error message (legacy alias for `title`)."},"title":{"type":"string","description":"Human-readable error message (RFC 9457)."},"status":{"type":"integer","description":"HTTP status code (RFC 9457)."},"statusCode":{"type":"integer","description":"HTTP status code (legacy alias for `status`)."},"type":{"type":"string","format":"uri","description":"URI pointing to the docs section for this error code (RFC 9457)."},"code":{"type":"string","description":"Machine-readable error code (stable identifier — see https://docs.billetsystems.com/errors)."},"request_id":{"type":"string","description":"Unique request identifier for support correlation."},"required_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the minimum tier needed to perform the operation."},"current_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the caller's current plan tier."},"errors":{"type":"array","description":"Per-field validation errors. Only present on 400 / 422 validation failures.","items":{"type":"object","properties":{"field":{"type":"string","description":"Dotted path of the failing field (e.g. `line_items.0.sku`)."},"message":{"type":"string","description":"Static, input-free description of the failure."},"code":{"type":"string","description":"Fixed-vocabulary field code — one of REQUIRED / INVALID_FORMAT / TOO_LONG / TOO_SHORT / TOO_BIG / TOO_SMALL / NOT_UNIQUE / INVALID_VALUE / TIER_LIMIT_EXCEEDED."}}}}},"required":["error"]}}}},"404":{"description":"Resource not found, or not owned by the authenticating company.","content":{"application/json":{"schema":{"description":"Resource not found, or not owned by the authenticating company.","type":"object","properties":{"error":{"type":"string","description":"Human-readable error message (legacy alias for `title`)."},"title":{"type":"string","description":"Human-readable error message (RFC 9457)."},"status":{"type":"integer","description":"HTTP status code (RFC 9457)."},"statusCode":{"type":"integer","description":"HTTP status code (legacy alias for `status`)."},"type":{"type":"string","format":"uri","description":"URI pointing to the docs section for this error code (RFC 9457)."},"code":{"type":"string","description":"Machine-readable error code (stable identifier — see https://docs.billetsystems.com/errors)."},"request_id":{"type":"string","description":"Unique request identifier for support correlation."},"required_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the minimum tier needed to perform the operation."},"current_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the caller's current plan tier."},"errors":{"type":"array","description":"Per-field validation errors. Only present on 400 / 422 validation failures.","items":{"type":"object","properties":{"field":{"type":"string","description":"Dotted path of the failing field (e.g. `line_items.0.sku`)."},"message":{"type":"string","description":"Static, input-free description of the failure."},"code":{"type":"string","description":"Fixed-vocabulary field code — one of REQUIRED / INVALID_FORMAT / TOO_LONG / TOO_SHORT / TOO_BIG / TOO_SMALL / NOT_UNIQUE / INVALID_VALUE / TIER_LIMIT_EXCEEDED."}}}}},"required":["error"]}}}}}}},"/api/v1/company":{"get":{"summary":"Get the authenticating company","tags":["Company"],"description":"Returns the company the current API key is scoped to. Useful for integration tools (Zapier, Make, n8n) that want to render a descriptive label for the connection — e.g. \"Acme Supply Co. (admin@acme.com)\". One API key always maps to exactly one company.","responses":{"200":{"description":"Company record.","content":{"application/json":{"schema":{"description":"Company record.","type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string","example":"Acme Plumbing Supply"},"plan_tier":{"type":"string","enum":["essentials","standard","professional"]},"currency":{"type":"string","enum":["USD","CAD","GBP","AUD","NZD"]},"billing_email":{"type":["null","string"],"format":"email"},"address_line1":{"type":["null","string"]},"city":{"type":["null","string"]},"state":{"type":["null","string"]},"zip":{"type":["null","string"]}}}}}}}},"401":{"description":"Missing, invalid, or deactivated API key.","content":{"application/json":{"schema":{"description":"Missing, invalid, or deactivated API key.","type":"object","properties":{"error":{"type":"string","description":"Human-readable error message (legacy alias for `title`)."},"title":{"type":"string","description":"Human-readable error message (RFC 9457)."},"status":{"type":"integer","description":"HTTP status code (RFC 9457)."},"statusCode":{"type":"integer","description":"HTTP status code (legacy alias for `status`)."},"type":{"type":"string","format":"uri","description":"URI pointing to the docs section for this error code (RFC 9457)."},"code":{"type":"string","description":"Machine-readable error code (stable identifier — see https://docs.billetsystems.com/errors)."},"request_id":{"type":"string","description":"Unique request identifier for support correlation."},"required_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the minimum tier needed to perform the operation."},"current_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the caller's current plan tier."},"errors":{"type":"array","description":"Per-field validation errors. Only present on 400 / 422 validation failures.","items":{"type":"object","properties":{"field":{"type":"string","description":"Dotted path of the failing field (e.g. `line_items.0.sku`)."},"message":{"type":"string","description":"Static, input-free description of the failure."},"code":{"type":"string","description":"Fixed-vocabulary field code — one of REQUIRED / INVALID_FORMAT / TOO_LONG / TOO_SHORT / TOO_BIG / TOO_SMALL / NOT_UNIQUE / INVALID_VALUE / TIER_LIMIT_EXCEEDED."}}}}},"required":["error"]}}}},"404":{"description":"Resource not found, or not owned by the authenticating company.","content":{"application/json":{"schema":{"description":"Resource not found, or not owned by the authenticating company.","type":"object","properties":{"error":{"type":"string","description":"Human-readable error message (legacy alias for `title`)."},"title":{"type":"string","description":"Human-readable error message (RFC 9457)."},"status":{"type":"integer","description":"HTTP status code (RFC 9457)."},"statusCode":{"type":"integer","description":"HTTP status code (legacy alias for `status`)."},"type":{"type":"string","format":"uri","description":"URI pointing to the docs section for this error code (RFC 9457)."},"code":{"type":"string","description":"Machine-readable error code (stable identifier — see https://docs.billetsystems.com/errors)."},"request_id":{"type":"string","description":"Unique request identifier for support correlation."},"required_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the minimum tier needed to perform the operation."},"current_tier":{"type":"string","description":"On 403 TIER_REQUIRED, the caller's current plan tier."},"errors":{"type":"array","description":"Per-field validation errors. Only present on 400 / 422 validation failures.","items":{"type":"object","properties":{"field":{"type":"string","description":"Dotted path of the failing field (e.g. `line_items.0.sku`)."},"message":{"type":"string","description":"Static, input-free description of the failure."},"code":{"type":"string","description":"Fixed-vocabulary field code — one of REQUIRED / INVALID_FORMAT / TOO_LONG / TOO_SHORT / TOO_BIG / TOO_SMALL / NOT_UNIQUE / INVALID_VALUE / TIER_LIMIT_EXCEEDED."}}}}},"required":["error"]}}}}}}}},"servers":[{"url":"https://api.billetsystems.com","description":"Production"}],"security":[{"ApiKey":[]}],"tags":[{"name":"Tickets","description":"Delivery tickets, invoices, estimates, SOCs, BOLs, transfers."},{"name":"Customers","description":"End-customer records (synced from QB/Xero/FB/Dynamics or created manually)."},{"name":"Products","description":"Product catalog / pricebook. Standard+ tier to create or update; read on all tiers."},{"name":"Webhooks","description":"Outbound webhook subscriptions. Billet POSTs signed JSON to your endpoint on ticket / customer / product events."},{"name":"Drivers","description":"Read-only list of drivers for assignment dropdowns."},{"name":"Branches","description":"Read-only list of branches (locations)."},{"name":"Company","description":"The authenticating company itself."}]}