{
    "openapi": "3.1.0",
    "info": {
        "title": "FieldStacker API",
        "version": "v1",
        "summary": "Connect your own FieldStacker account to your own systems.",
        "description": "The API is for a business connecting its OWN FieldStacker account to its own systems (API Terms: https://www.fieldstacker.com/api-terms.php).\n\n**URL shape.** The route is in the query string: `https://www.fieldstacker.com/app/api.php?route=v1/<path>`. Add other query parameters with `&` (`…?route=v1/customers&limit=20`), not a second `?`.\n\n**Answers.** One object: `{\"ok\":true,\"data\":…}`; a list adds `next_cursor` and `limit`. Errors: `{\"ok\":false,\"error\":{\"code\",\"message\",\"field\"}}`. The older leads routes and v1/me keep their first shape. Times are ISO 8601 with the business's offset; money is a decimal string with `currency`.\n\n**Limits.** 60 requests a minute per key (429 + Retry-After). POST takes an Idempotency-Key.",
        "termsOfService": "https://www.fieldstacker.com/api-terms.php",
        "contact": {
            "name": "FieldStacker support",
            "url": "https://www.fieldstacker.com/developers.php"
        }
    },
    "servers": [
        {
            "url": "https://www.fieldstacker.com/app/api.php?route=v1",
            "description": "Production. Paths are appended to this URL; extra query parameters join with &."
        }
    ],
    "security": [
        {
            "bearerAuth": []
        },
        {
            "apiKeyHeader": []
        }
    ],
    "tags": [
        {
            "name": "Account",
            "description": "The key's business, usage and this description."
        },
        {
            "name": "Leads",
            "description": "Map pins. The older shape: no data wrapper, numbers for numbers."
        },
        {
            "name": "Customers"
        },
        {
            "name": "Bookings"
        },
        {
            "name": "Estimates & invoices"
        },
        {
            "name": "Price list"
        },
        {
            "name": "Form leads"
        },
        {
            "name": "Webhooks",
            "description": "Manage webhooks, read the delivery log, list the events. Each POST is signed: X-FieldStacker-Signature = \"sha256=\" + hex HMAC-SHA256 of the raw body with the webhook's secret."
        },
        {
            "name": "Commerce"
        },
        {
            "name": "Operations"
        },
        {
            "name": "Documents & field records"
        }
    ],
    "paths": {
        "/me": {
            "get": {
                "tags": [
                    "Account"
                ],
                "operationId": "getMe",
                "summary": "The business this key belongs to (a connection test).",
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Me"
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            }
        },
        "/leads": {
            "get": {
                "tags": [
                    "Leads"
                ],
                "operationId": "listLeads",
                "summary": "Leads created since a time (a bare JSON array, newest first — the polling shape).",
                "parameters": [
                    {
                        "name": "since",
                        "in": "query",
                        "required": false,
                        "description": "Default 7 days ago. ISO 8601 (no offset = the business's local time), YYYY-MM-DD or unix seconds.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "limit",
                        "in": "query",
                        "required": false,
                        "description": "1–100 (default 100).",
                        "schema": {
                            "type": "integer",
                            "minimum": 1,
                            "maximum": 100
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "array",
                                    "items": {
                                        "$ref": "#/components/schemas/Lead"
                                    }
                                }
                            }
                        }
                    },
                    "422": {
                        "$ref": "#/components/responses/E422"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            },
            "post": {
                "tags": [
                    "Leads"
                ],
                "operationId": "createLead",
                "summary": "Add a lead (a pin on the map). Fires lead.created unless notify_webhooks is false.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/idempotencyKey"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/LeadCreate"
                            }
                        },
                        "application/x-www-form-urlencoded": {
                            "schema": {
                                "$ref": "#/components/schemas/LeadCreate"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Created",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LeadAnswer"
                                }
                            }
                        }
                    },
                    "200": {
                        "description": "The same external_id / Idempotency-Key again: the first lead, duplicate: true.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LeadAnswer"
                                }
                            }
                        }
                    },
                    "409": {
                        "$ref": "#/components/responses/E409"
                    },
                    "422": {
                        "$ref": "#/components/responses/E422"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            }
        },
        "/leads/{id}": {
            "parameters": [
                {
                    "name": "id",
                    "in": "path",
                    "required": true,
                    "description": "Lead id.",
                    "schema": {
                        "type": "integer"
                    }
                }
            ],
            "get": {
                "tags": [
                    "Leads"
                ],
                "operationId": "getLead",
                "summary": "One lead.",
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "ok": {
                                            "const": true
                                        },
                                        "lead": {
                                            "$ref": "#/components/schemas/Lead"
                                        }
                                    },
                                    "required": [
                                        "ok",
                                        "lead"
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/E404"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            },
            "patch": {
                "tags": [
                    "Leads"
                ],
                "operationId": "updateLead",
                "summary": "Change status and/or notes. Fires lead.status_changed (+ lead.sold / appointment.created).",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/LeadPatch"
                            }
                        },
                        "application/x-www-form-urlencoded": {
                            "schema": {
                                "$ref": "#/components/schemas/LeadPatch"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "ok": {
                                            "const": true
                                        },
                                        "lead": {
                                            "$ref": "#/components/schemas/Lead"
                                        }
                                    },
                                    "required": [
                                        "ok",
                                        "lead"
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/E404"
                    },
                    "422": {
                        "$ref": "#/components/responses/E422"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            }
        },
        "/customers": {
            "get": {
                "tags": [
                    "Customers"
                ],
                "operationId": "listCustomers",
                "summary": "Customers, most recent activity first. Plan: Customers.",
                "parameters": [
                    {
                        "name": "q",
                        "in": "query",
                        "required": false,
                        "description": "Search name, business, phone (or its digits), email, address, tags across every record.",
                        "schema": {
                            "type": "string",
                            "maxLength": 100
                        }
                    },
                    {
                        "name": "updated_since",
                        "in": "query",
                        "required": false,
                        "description": "Last activity or edit at or after. ISO 8601 (no offset = the business's local time), YYYY-MM-DD or unix seconds.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "$ref": "#/components/parameters/limit"
                    },
                    {
                        "$ref": "#/components/parameters/cursor"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "data",
                                        "next_cursor",
                                        "limit"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "const": true
                                        },
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/Customer"
                                            }
                                        },
                                        "next_cursor": {
                                            "type": [
                                                "string",
                                                "null"
                                            ],
                                            "description": "Pass as `cursor` (with the same filters) for the next page; null on the last page."
                                        },
                                        "limit": {
                                            "type": "integer"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/E400"
                    },
                    "503": {
                        "$ref": "#/components/responses/E503"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            },
            "post": {
                "tags": [
                    "Customers"
                ],
                "operationId": "createCustomer",
                "summary": "Add a customer (like ＋ Add customer). An existing match answers 200 existing: true and writes nothing.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/idempotencyKey"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/CustomerCreate"
                            }
                        },
                        "application/x-www-form-urlencoded": {
                            "schema": {
                                "$ref": "#/components/schemas/CustomerCreate"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Created",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "data"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "const": true
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/Customer"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "200": {
                        "description": "An existing customer matched.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "type": "object",
                                            "required": [
                                                "ok",
                                                "data"
                                            ],
                                            "properties": {
                                                "ok": {
                                                    "const": true
                                                },
                                                "data": {
                                                    "$ref": "#/components/schemas/Customer"
                                                }
                                            }
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "existing": {
                                                    "const": true
                                                }
                                            },
                                            "required": [
                                                "existing"
                                            ]
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/E400"
                    },
                    "409": {
                        "$ref": "#/components/responses/E409"
                    },
                    "422": {
                        "$ref": "#/components/responses/E422"
                    },
                    "503": {
                        "$ref": "#/components/responses/E503"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            }
        },
        "/customers/{id}": {
            "parameters": [
                {
                    "name": "id",
                    "in": "path",
                    "required": true,
                    "description": "cus_… — any of the customer's record ids.",
                    "schema": {
                        "type": "string"
                    }
                }
            ],
            "get": {
                "tags": [
                    "Customers"
                ],
                "operationId": "getCustomer",
                "summary": "One customer.",
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "data"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "const": true
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/Customer"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/E404"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            },
            "patch": {
                "tags": [
                    "Customers"
                ],
                "operationId": "updateCustomer",
                "summary": "Edit what FieldStacker shows for the customer (like ✏️ Edit customer).",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/CustomerPatch"
                            }
                        },
                        "application/x-www-form-urlencoded": {
                            "schema": {
                                "$ref": "#/components/schemas/CustomerPatch"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "data"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "const": true
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/Customer"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/E404"
                    },
                    "422": {
                        "$ref": "#/components/responses/E422"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            }
        },
        "/bookings": {
            "get": {
                "tags": [
                    "Bookings"
                ],
                "operationId": "listBookings",
                "summary": "Online bookings and schedule appointments, by start time (oldest first).",
                "parameters": [
                    {
                        "name": "from",
                        "in": "query",
                        "required": false,
                        "description": "Start at or after (default 30 days ago). ISO 8601 (no offset = the business's local time), YYYY-MM-DD or unix seconds.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "to",
                        "in": "query",
                        "required": false,
                        "description": "Start before (a date = the end of that day). ISO 8601 (no offset = the business's local time), YYYY-MM-DD or unix seconds.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "status",
                        "in": "query",
                        "required": false,
                        "description": "Comma-separated: pending, confirmed, canceled, declined, completed, no_show.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "type",
                        "in": "query",
                        "required": false,
                        "description": "online_booking or appointment.",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "online_booking",
                                "appointment"
                            ]
                        }
                    },
                    {
                        "$ref": "#/components/parameters/limit"
                    },
                    {
                        "$ref": "#/components/parameters/cursor"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "data",
                                        "next_cursor",
                                        "limit"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "const": true
                                        },
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/Booking"
                                            }
                                        },
                                        "next_cursor": {
                                            "type": [
                                                "string",
                                                "null"
                                            ],
                                            "description": "Pass as `cursor` (with the same filters) for the next page; null on the last page."
                                        },
                                        "limit": {
                                            "type": "integer"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/E400"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            },
            "post": {
                "tags": [
                    "Bookings"
                ],
                "operationId": "createBooking",
                "summary": "Book an open time through the booking page's own path (the owner is notified; the customer gets the same email / text as a website booking).",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/idempotencyKey"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/BookingCreate"
                            }
                        },
                        "application/x-www-form-urlencoded": {
                            "schema": {
                                "$ref": "#/components/schemas/BookingCreate"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Created",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "type": "object",
                                            "required": [
                                                "ok",
                                                "data"
                                            ],
                                            "properties": {
                                                "ok": {
                                                    "const": true
                                                },
                                                "data": {
                                                    "$ref": "#/components/schemas/Booking"
                                                }
                                            }
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "needs_approval": {
                                                    "type": "boolean"
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "409": {
                        "$ref": "#/components/responses/E409"
                    },
                    "422": {
                        "$ref": "#/components/responses/E422"
                    },
                    "503": {
                        "$ref": "#/components/responses/E503"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            }
        },
        "/bookings/{id}": {
            "parameters": [
                {
                    "name": "id",
                    "in": "path",
                    "required": true,
                    "description": "bk_<id> or ap_<id>.",
                    "schema": {
                        "type": "string"
                    }
                }
            ],
            "get": {
                "tags": [
                    "Bookings"
                ],
                "operationId": "getBooking",
                "summary": "One booking.",
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "data"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "const": true
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/Booking"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/E404"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            },
            "patch": {
                "tags": [
                    "Bookings"
                ],
                "operationId": "updateBooking",
                "summary": "Move, cancel or confirm an online booking (website service bookings: move or cancel).",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/BookingPatch"
                            }
                        },
                        "application/x-www-form-urlencoded": {
                            "schema": {
                                "$ref": "#/components/schemas/BookingPatch"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "data"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "const": true
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/Booking"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/E404"
                    },
                    "409": {
                        "$ref": "#/components/responses/E409"
                    },
                    "422": {
                        "$ref": "#/components/responses/E422"
                    },
                    "503": {
                        "$ref": "#/components/responses/E503"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            }
        },
        "/availability": {
            "get": {
                "tags": [
                    "Bookings"
                ],
                "operationId": "getAvailability",
                "summary": "Open booking times, the services and the intake questions.",
                "parameters": [
                    {
                        "name": "date",
                        "in": "query",
                        "required": false,
                        "description": "YYYY-MM-DD: the open start times that day. Without it: the next dates with any.",
                        "schema": {
                            "type": "string",
                            "format": "date"
                        }
                    },
                    {
                        "name": "service",
                        "in": "query",
                        "required": false,
                        "description": "A service key.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "data"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "const": true
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/Availability"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/E400"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            }
        },
        "/estimates": {
            "get": {
                "tags": [
                    "Estimates & invoices"
                ],
                "operationId": "listEstimates",
                "summary": "Estimates, most recently changed first (read-only). Plan: business_suite.",
                "parameters": [
                    {
                        "name": "status",
                        "in": "query",
                        "required": false,
                        "description": "draft, sent or approved.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "updated_since",
                        "in": "query",
                        "required": false,
                        "description": "Changed at or after. ISO 8601 (no offset = the business's local time), YYYY-MM-DD or unix seconds.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "$ref": "#/components/parameters/limit"
                    },
                    {
                        "$ref": "#/components/parameters/cursor"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "data",
                                        "next_cursor",
                                        "limit"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "const": true
                                        },
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/Estimate"
                                            }
                                        },
                                        "next_cursor": {
                                            "type": [
                                                "string",
                                                "null"
                                            ],
                                            "description": "Pass as `cursor` (with the same filters) for the next page; null on the last page."
                                        },
                                        "limit": {
                                            "type": "integer"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/E400"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            },
            "post": {
                "tags": [
                    "Estimates & invoices"
                ],
                "operationId": "createEstimate",
                "summary": "Make a draft estimate for a customer, the way the app starts one (numbered, your usual tax rate, owned by the business owner). Plan: business_suite.",
                "description": "sj_from_start() makes it; each line goes through sidejob_item_add() (+ your automatic line rules). All in one transaction: a refused line creates nothing. Nothing is sent to anyone.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/idempotencyKey"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/DocCreate"
                            }
                        },
                        "application/x-www-form-urlencoded": {
                            "schema": {
                                "$ref": "#/components/schemas/DocCreate"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Created",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "data"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "const": true
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/EstimateWritten"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/E400"
                    },
                    "404": {
                        "$ref": "#/components/responses/E404"
                    },
                    "409": {
                        "$ref": "#/components/responses/E409"
                    },
                    "422": {
                        "$ref": "#/components/responses/E422"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            }
        },
        "/estimates/{id}": {
            "parameters": [
                {
                    "name": "id",
                    "in": "path",
                    "required": true,
                    "description": "Estimate id.",
                    "schema": {
                        "type": "integer"
                    }
                }
            ],
            "get": {
                "tags": [
                    "Estimates & invoices"
                ],
                "operationId": "getEstimate",
                "summary": "One estimate.",
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "data"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "const": true
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/Estimate"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/E404"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            },
            "patch": {
                "tags": [
                    "Estimates & invoices"
                ],
                "operationId": "updateEstimate",
                "summary": "Replace a DRAFT estimate's customer lines (a sent, approved, in-progress or paid one is 409 not_draft).",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/DocPatch"
                            }
                        },
                        "application/x-www-form-urlencoded": {
                            "schema": {
                                "$ref": "#/components/schemas/DocPatch"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "data"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "const": true
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/EstimateWritten"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/E404"
                    },
                    "409": {
                        "$ref": "#/components/responses/E409"
                    },
                    "422": {
                        "$ref": "#/components/responses/E422"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            }
        },
        "/invoices": {
            "get": {
                "tags": [
                    "Estimates & invoices"
                ],
                "operationId": "listInvoices",
                "summary": "Invoices, most recently changed first (read-only). Plan: business_suite.",
                "parameters": [
                    {
                        "name": "status",
                        "in": "query",
                        "required": false,
                        "description": "draft, in_progress, sent, unpaid or paid.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "updated_since",
                        "in": "query",
                        "required": false,
                        "description": "Changed at or after. ISO 8601 (no offset = the business's local time), YYYY-MM-DD or unix seconds.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "$ref": "#/components/parameters/limit"
                    },
                    {
                        "$ref": "#/components/parameters/cursor"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "data",
                                        "next_cursor",
                                        "limit"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "const": true
                                        },
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/Invoice"
                                            }
                                        },
                                        "next_cursor": {
                                            "type": [
                                                "string",
                                                "null"
                                            ],
                                            "description": "Pass as `cursor` (with the same filters) for the next page; null on the last page."
                                        },
                                        "limit": {
                                            "type": "integer"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/E400"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            },
            "post": {
                "tags": [
                    "Estimates & invoices"
                ],
                "operationId": "createInvoice",
                "summary": "Make a draft invoice for a customer, the way the app starts one (numbered, your usual tax rate, owned by the business owner). Plan: business_suite.",
                "description": "sj_from_start() makes it; each line goes through sidejob_item_add() (+ your automatic line rules). All in one transaction: a refused line creates nothing. Nothing is sent to anyone.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/idempotencyKey"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/DocCreate"
                            }
                        },
                        "application/x-www-form-urlencoded": {
                            "schema": {
                                "$ref": "#/components/schemas/DocCreate"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Created",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "data"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "const": true
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/InvoiceWritten"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/E400"
                    },
                    "404": {
                        "$ref": "#/components/responses/E404"
                    },
                    "409": {
                        "$ref": "#/components/responses/E409"
                    },
                    "422": {
                        "$ref": "#/components/responses/E422"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            }
        },
        "/invoices/{id}": {
            "parameters": [
                {
                    "name": "id",
                    "in": "path",
                    "required": true,
                    "description": "Invoice id.",
                    "schema": {
                        "type": "integer"
                    }
                }
            ],
            "get": {
                "tags": [
                    "Estimates & invoices"
                ],
                "operationId": "getInvoice",
                "summary": "One invoice.",
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "data"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "const": true
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/Invoice"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/E404"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            },
            "patch": {
                "tags": [
                    "Estimates & invoices"
                ],
                "operationId": "updateInvoice",
                "summary": "Replace a DRAFT invoice's customer lines (a sent, approved, in-progress or paid one is 409 not_draft).",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/DocPatch"
                            }
                        },
                        "application/x-www-form-urlencoded": {
                            "schema": {
                                "$ref": "#/components/schemas/DocPatch"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "data"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "const": true
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/InvoiceWritten"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/E404"
                    },
                    "409": {
                        "$ref": "#/components/responses/E409"
                    },
                    "422": {
                        "$ref": "#/components/responses/E422"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            }
        },
        "/services": {
            "get": {
                "tags": [
                    "Price list"
                ],
                "operationId": "listServices",
                "summary": "The price list (not hidden items). Plan: quoting or business_suite.",
                "parameters": [
                    {
                        "name": "q",
                        "in": "query",
                        "required": false,
                        "description": "Name or model contains.",
                        "schema": {
                            "type": "string",
                            "maxLength": 100
                        }
                    },
                    {
                        "name": "category",
                        "in": "query",
                        "required": false,
                        "description": "Exact category (any case).",
                        "schema": {
                            "type": "string",
                            "maxLength": 40
                        }
                    },
                    {
                        "$ref": "#/components/parameters/limit"
                    },
                    {
                        "$ref": "#/components/parameters/cursor"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "data",
                                        "next_cursor",
                                        "limit"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "const": true
                                        },
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/Service"
                                            }
                                        },
                                        "next_cursor": {
                                            "type": [
                                                "string",
                                                "null"
                                            ],
                                            "description": "Pass as `cursor` (with the same filters) for the next page; null on the last page."
                                        },
                                        "limit": {
                                            "type": "integer"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/E400"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            }
        },
        "/form-leads": {
            "get": {
                "tags": [
                    "Form leads"
                ],
                "operationId": "listFormLeads",
                "summary": "Website, landing-page and card form leads, newest first (read-only).",
                "parameters": [
                    {
                        "name": "since",
                        "in": "query",
                        "required": false,
                        "description": "Created after. ISO 8601 (no offset = the business's local time), YYYY-MM-DD or unix seconds.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "source",
                        "in": "query",
                        "required": false,
                        "description": "website_message, website_form, landing_page or card.",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "website_message",
                                "website_form",
                                "landing_page",
                                "card"
                            ]
                        }
                    },
                    {
                        "$ref": "#/components/parameters/limit"
                    },
                    {
                        "$ref": "#/components/parameters/cursor"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "data",
                                        "next_cursor",
                                        "limit"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "const": true
                                        },
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/FormLead"
                                            }
                                        },
                                        "next_cursor": {
                                            "type": [
                                                "string",
                                                "null"
                                            ],
                                            "description": "Pass as `cursor` (with the same filters) for the next page; null on the last page."
                                        },
                                        "limit": {
                                            "type": "integer"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/E400"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            }
        },
        "/form-leads/{id}": {
            "parameters": [
                {
                    "name": "id",
                    "in": "path",
                    "required": true,
                    "description": "msg_<id>, lp_<id> or card_<id>.",
                    "schema": {
                        "type": "string"
                    }
                }
            ],
            "get": {
                "tags": [
                    "Form leads"
                ],
                "operationId": "getFormLead",
                "summary": "One form lead.",
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "data"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "const": true
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/FormLead"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/E404"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            }
        },
        "/webhooks": {
            "get": {
                "tags": [
                    "Webhooks"
                ],
                "operationId": "listWebhooks",
                "summary": "Your webhooks (up to 5), oldest first. Never the signing secret.",
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "type": "object",
                                            "required": [
                                                "ok",
                                                "data",
                                                "next_cursor",
                                                "limit"
                                            ],
                                            "properties": {
                                                "ok": {
                                                    "const": true
                                                },
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/Webhook"
                                                    }
                                                },
                                                "next_cursor": {
                                                    "type": [
                                                        "string",
                                                        "null"
                                                    ],
                                                    "description": "Pass as `cursor` (with the same filters) for the next page; null on the last page."
                                                },
                                                "limit": {
                                                    "type": "integer"
                                                }
                                            }
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "max_webhooks": {
                                                    "type": "integer"
                                                }
                                            },
                                            "required": [
                                                "max_webhooks"
                                            ]
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            },
            "post": {
                "tags": [
                    "Webhooks"
                ],
                "operationId": "createWebhook",
                "summary": "Add a webhook. The answer carries the signing secret ONCE.",
                "description": "Same checks as Settings → API & webhooks: https on a public host (re-checked at every send, no redirects followed), at least one event, at most 5 webhooks. The same URL twice is 409 duplicate_url.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/idempotencyKey"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/WebhookCreate"
                            }
                        },
                        "application/x-www-form-urlencoded": {
                            "schema": {
                                "$ref": "#/components/schemas/WebhookCreate"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Created",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "data"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "const": true
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/WebhookCreated"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/E400"
                    },
                    "409": {
                        "$ref": "#/components/responses/E409"
                    },
                    "422": {
                        "$ref": "#/components/responses/E422"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            }
        },
        "/webhooks/{id}": {
            "parameters": [
                {
                    "name": "id",
                    "in": "path",
                    "required": true,
                    "description": "Webhook id.",
                    "schema": {
                        "type": "integer"
                    }
                }
            ],
            "get": {
                "tags": [
                    "Webhooks"
                ],
                "operationId": "getWebhook",
                "summary": "One webhook.",
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "data"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "const": true
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/Webhook"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/E404"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            },
            "patch": {
                "tags": [
                    "Webhooks"
                ],
                "operationId": "updateWebhook",
                "summary": "Change its label, URL or events, or pause / resume it.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/WebhookPatch"
                            }
                        },
                        "application/x-www-form-urlencoded": {
                            "schema": {
                                "$ref": "#/components/schemas/WebhookPatch"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "data"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "const": true
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/Webhook"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/E404"
                    },
                    "409": {
                        "$ref": "#/components/responses/E409"
                    },
                    "422": {
                        "$ref": "#/components/responses/E422"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            },
            "delete": {
                "tags": [
                    "Webhooks"
                ],
                "operationId": "deleteWebhook",
                "summary": "Delete it. Its queued deliveries are dropped; the log keeps the finished ones.",
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "data"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "const": true
                                        },
                                        "data": {
                                            "type": "object",
                                            "properties": {
                                                "id": {
                                                    "type": "integer"
                                                },
                                                "deleted": {
                                                    "const": true
                                                }
                                            },
                                            "required": [
                                                "id",
                                                "deleted"
                                            ]
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/E404"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            }
        },
        "/webhooks/{id}/test": {
            "parameters": [
                {
                    "name": "id",
                    "in": "path",
                    "required": true,
                    "description": "Webhook id.",
                    "schema": {
                        "type": "integer"
                    }
                }
            ],
            "post": {
                "tags": [
                    "Webhooks"
                ],
                "operationId": "testWebhook",
                "summary": "Send a signed test event (\"test\": true) to it now. Works while paused; never retried. At most 5 a minute.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/idempotencyKey"
                    }
                ],
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "event": {
                                        "type": "string",
                                        "enum": [
                                            "lead.created",
                                            "lead.status_changed",
                                            "lead.sold",
                                            "appointment.created",
                                            "quote.approved",
                                            "invoice.paid",
                                            "booking.requested",
                                            "booking.rescheduled",
                                            "booking.canceled",
                                            "website.form",
                                            "campaign.lead",
                                            "chat.lead",
                                            "card.lead",
                                            "review.received",
                                            "lighting.reply",
                                            "lighting.postcard_opened"
                                        ],
                                        "description": "Default: the webhook's first event."
                                    }
                                }
                            }
                        },
                        "application/x-www-form-urlencoded": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "event": {
                                        "type": "string",
                                        "enum": [
                                            "lead.created",
                                            "lead.status_changed",
                                            "lead.sold",
                                            "appointment.created",
                                            "quote.approved",
                                            "invoice.paid",
                                            "booking.requested",
                                            "booking.rescheduled",
                                            "booking.canceled",
                                            "website.form",
                                            "campaign.lead",
                                            "chat.lead",
                                            "card.lead",
                                            "review.received",
                                            "lighting.reply",
                                            "lighting.postcard_opened"
                                        ],
                                        "description": "Default: the webhook's first event."
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Sent (data.delivered says whether the receiver took it).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "data"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "const": true
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/WebhookTestResult"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/E400"
                    },
                    "404": {
                        "$ref": "#/components/responses/E404"
                    },
                    "422": {
                        "$ref": "#/components/responses/E422"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            }
        },
        "/webhooks/deliveries": {
            "get": {
                "tags": [
                    "Webhooks"
                ],
                "operationId": "listDeliveries",
                "summary": "The delivery log (30 days), newest first.",
                "parameters": [
                    {
                        "name": "webhook_id",
                        "in": "query",
                        "required": false,
                        "description": "Only this webhook.",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "name": "event",
                        "in": "query",
                        "required": false,
                        "description": "Only this event.",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "lead.created",
                                "lead.status_changed",
                                "lead.sold",
                                "appointment.created",
                                "quote.approved",
                                "invoice.paid",
                                "booking.requested",
                                "booking.rescheduled",
                                "booking.canceled",
                                "website.form",
                                "campaign.lead",
                                "chat.lead",
                                "card.lead",
                                "review.received",
                                "lighting.reply",
                                "lighting.postcard_opened"
                            ]
                        }
                    },
                    {
                        "name": "status",
                        "in": "query",
                        "required": false,
                        "description": "Comma-separated: delivered, failed, retrying, queued, sending, held, skipped.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "since",
                        "in": "query",
                        "required": false,
                        "description": "Queued at or after. ISO 8601 (no offset = the business's local time), YYYY-MM-DD or unix seconds.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "$ref": "#/components/parameters/limit"
                    },
                    {
                        "$ref": "#/components/parameters/cursor"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "data",
                                        "next_cursor",
                                        "limit"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "const": true
                                        },
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/Delivery"
                                            }
                                        },
                                        "next_cursor": {
                                            "type": [
                                                "string",
                                                "null"
                                            ],
                                            "description": "Pass as `cursor` (with the same filters) for the next page; null on the last page."
                                        },
                                        "limit": {
                                            "type": "integer"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/E400"
                    },
                    "404": {
                        "$ref": "#/components/responses/E404"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            }
        },
        "/events": {
            "get": {
                "tags": [
                    "Webhooks"
                ],
                "operationId": "listEvents",
                "summary": "Every event a webhook can subscribe to.",
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "type": "object",
                                            "required": [
                                                "ok",
                                                "data",
                                                "next_cursor",
                                                "limit"
                                            ],
                                            "properties": {
                                                "ok": {
                                                    "const": true
                                                },
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/EventType"
                                                    }
                                                },
                                                "next_cursor": {
                                                    "type": [
                                                        "string",
                                                        "null"
                                                    ],
                                                    "description": "Pass as `cursor` (with the same filters) for the next page; null on the last page."
                                                },
                                                "limit": {
                                                    "type": "integer"
                                                }
                                            }
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "api_version": {
                                                    "type": "string"
                                                }
                                            },
                                            "required": [
                                                "api_version"
                                            ]
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            }
        },
        "/events/{event}": {
            "parameters": [
                {
                    "name": "event",
                    "in": "path",
                    "required": true,
                    "description": "An event key, e.g. lead.created.",
                    "schema": {
                        "type": "string",
                        "enum": [
                            "lead.created",
                            "lead.status_changed",
                            "lead.sold",
                            "appointment.created",
                            "quote.approved",
                            "invoice.paid",
                            "booking.requested",
                            "booking.rescheduled",
                            "booking.canceled",
                            "website.form",
                            "campaign.lead",
                            "chat.lead",
                            "card.lead",
                            "review.received",
                            "lighting.reply",
                            "lighting.postcard_opened"
                        ]
                    }
                }
            ],
            "get": {
                "tags": [
                    "Webhooks"
                ],
                "operationId": "getEvent",
                "summary": "One event type + a sample payload (nothing is sent).",
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "data"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "const": true
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/EventDetail"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/E404"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            }
        },
        "/usage": {
            "get": {
                "tags": [
                    "Account"
                ],
                "operationId": "getUsage",
                "summary": "This key's rate-limit window and request counts (read-only).",
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "data"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "const": true
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/Usage"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/E404"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            }
        },
        "/openapi.json": {
            "get": {
                "tags": [
                    "Account"
                ],
                "operationId": "getOpenApi",
                "summary": "This description. No key needed.",
                "security": [],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "description": "An OpenAPI 3.1 document."
                                }
                            }
                        }
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    }
                }
            }
        },
        "/products": {
            "get": {
                "tags": [
                    "Commerce"
                ],
                "operationId": "listProducts",
                "summary": "The price list, by id (read-only). Plan: quoting or business_suite.",
                "parameters": [
                    {
                        "name": "q",
                        "in": "query",
                        "required": false,
                        "description": "Name or SKU contains.",
                        "schema": {
                            "type": "string",
                            "maxLength": 100
                        }
                    },
                    {
                        "name": "category",
                        "in": "query",
                        "required": false,
                        "description": "Exact category (any case).",
                        "schema": {
                            "type": "string",
                            "maxLength": 40
                        }
                    },
                    {
                        "name": "active",
                        "in": "query",
                        "required": false,
                        "description": "true (default), false (hidden items) or all.",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "true",
                                "false",
                                "all"
                            ],
                            "default": "true"
                        }
                    },
                    {
                        "$ref": "#/components/parameters/limit"
                    },
                    {
                        "$ref": "#/components/parameters/cursor"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "data",
                                        "next_cursor",
                                        "limit"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "const": true
                                        },
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/Product"
                                            }
                                        },
                                        "next_cursor": {
                                            "type": [
                                                "string",
                                                "null"
                                            ],
                                            "description": "Pass as `cursor` (with the same filters) for the next page; null on the last page."
                                        },
                                        "limit": {
                                            "type": "integer"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/E400"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            }
        },
        "/products/{id}": {
            "parameters": [
                {
                    "name": "id",
                    "in": "path",
                    "required": true,
                    "description": "Product id.",
                    "schema": {
                        "type": "integer"
                    }
                }
            ],
            "get": {
                "tags": [
                    "Commerce"
                ],
                "operationId": "getProduct",
                "summary": "One product (a hidden one answers with active: false).",
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "data"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "const": true
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/Product"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/E404"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            }
        },
        "/inventory": {
            "get": {
                "tags": [
                    "Commerce"
                ],
                "operationId": "listInventory",
                "summary": "Stock on hand per person, with the low-stock flag. Plan: inventory (tech tools).",
                "parameters": [
                    {
                        "name": "source",
                        "in": "query",
                        "required": false,
                        "description": "install_inventory or sub_dealer_stock.",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "install_inventory",
                                "sub_dealer_stock"
                            ]
                        }
                    },
                    {
                        "name": "held_by",
                        "in": "query",
                        "required": false,
                        "description": "rep_<id>.",
                        "schema": {
                            "type": "string",
                            "pattern": "^rep_[1-9]\\d*$"
                        }
                    },
                    {
                        "name": "low_stock",
                        "in": "query",
                        "required": false,
                        "description": "true = at or under its low-stock level; false = not.",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "true",
                                "false"
                            ]
                        }
                    },
                    {
                        "name": "q",
                        "in": "query",
                        "required": false,
                        "description": "Name or SKU contains.",
                        "schema": {
                            "type": "string",
                            "maxLength": 100
                        }
                    },
                    {
                        "name": "updated_since",
                        "in": "query",
                        "required": false,
                        "description": "Changed at or after. ISO 8601 (no offset = the business's local time), YYYY-MM-DD or unix seconds.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "$ref": "#/components/parameters/limit"
                    },
                    {
                        "$ref": "#/components/parameters/cursor"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "data",
                                        "next_cursor",
                                        "limit"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "const": true
                                        },
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/InventoryItem"
                                            }
                                        },
                                        "next_cursor": {
                                            "type": [
                                                "string",
                                                "null"
                                            ],
                                            "description": "Pass as `cursor` (with the same filters) for the next page; null on the last page."
                                        },
                                        "limit": {
                                            "type": "integer"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/E400"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            }
        },
        "/inventory/movements": {
            "get": {
                "tags": [
                    "Commerce"
                ],
                "operationId": "listInventoryMovements",
                "summary": "The install inventory's stock in / out log, newest first.",
                "parameters": [
                    {
                        "name": "item_id",
                        "in": "query",
                        "required": false,
                        "description": "inv_<id> (sub-dealer stock keeps no log).",
                        "schema": {
                            "type": "string",
                            "pattern": "^inv_[1-9]\\d*$"
                        }
                    },
                    {
                        "name": "held_by",
                        "in": "query",
                        "required": false,
                        "description": "rep_<id>.",
                        "schema": {
                            "type": "string",
                            "pattern": "^rep_[1-9]\\d*$"
                        }
                    },
                    {
                        "name": "reason",
                        "in": "query",
                        "required": false,
                        "description": "One reason.",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "receive",
                                "use",
                                "install",
                                "adjust",
                                "transfer",
                                "side_job"
                            ]
                        }
                    },
                    {
                        "name": "since",
                        "in": "query",
                        "required": false,
                        "description": "At or after. ISO 8601 (no offset = the business's local time), YYYY-MM-DD or unix seconds.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "until",
                        "in": "query",
                        "required": false,
                        "description": "Before (a date = the end of that day). ISO 8601 (no offset = the business's local time), YYYY-MM-DD or unix seconds.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "$ref": "#/components/parameters/limit"
                    },
                    {
                        "$ref": "#/components/parameters/cursor"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "data",
                                        "next_cursor",
                                        "limit"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "const": true
                                        },
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/InventoryMovement"
                                            }
                                        },
                                        "next_cursor": {
                                            "type": [
                                                "string",
                                                "null"
                                            ],
                                            "description": "Pass as `cursor` (with the same filters) for the next page; null on the last page."
                                        },
                                        "limit": {
                                            "type": "integer"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/E400"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            }
        },
        "/inventory/{id}": {
            "parameters": [
                {
                    "name": "id",
                    "in": "path",
                    "required": true,
                    "description": "inv_<id> or sub_<id>.",
                    "schema": {
                        "type": "string",
                        "pattern": "^(inv|sub)_[1-9]\\d*$"
                    }
                }
            ],
            "get": {
                "tags": [
                    "Commerce"
                ],
                "operationId": "getInventoryItem",
                "summary": "One inventory item.",
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "data"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "const": true
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/InventoryItem"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/E404"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            }
        },
        "/inventory/{id}/adjust": {
            "parameters": [
                {
                    "name": "id",
                    "in": "path",
                    "required": true,
                    "description": "inv_<id> (install inventory).",
                    "schema": {
                        "type": "string",
                        "pattern": "^(inv|sub)_[1-9]\\d*$"
                    }
                }
            ],
            "post": {
                "tags": [
                    "Commerce"
                ],
                "operationId": "adjustInventoryItem",
                "summary": "Change an install-inventory count through the app's own writer (row lock, never below 0, the movement logged).",
                "description": "The same as the ▲/▼ arrows and the typed count on the Inventory page. Sub-dealer stock answers 409 not_adjustable.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/idempotencyKey"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/InventoryAdjust"
                            }
                        },
                        "application/x-www-form-urlencoded": {
                            "schema": {
                                "$ref": "#/components/schemas/InventoryAdjust"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/InventoryAdjustAnswer"
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/E400"
                    },
                    "404": {
                        "$ref": "#/components/responses/E404"
                    },
                    "409": {
                        "$ref": "#/components/responses/E409"
                    },
                    "422": {
                        "$ref": "#/components/responses/E422"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            }
        },
        "/estimates/{id}/send": {
            "parameters": [
                {
                    "name": "id",
                    "in": "path",
                    "required": true,
                    "description": "Estimate id.",
                    "schema": {
                        "type": "integer"
                    }
                }
            ],
            "post": {
                "tags": [
                    "Estimates & invoices"
                ],
                "operationId": "sendEstimate",
                "summary": "⚠️ Emails the estimate to its customer through the app's own send (letterhead email from your business, approve link). No body.",
                "description": "Emailed in the last 10 minutes is 409 recently_sent; no lines yet is 422 no_total. Send an Idempotency-Key so a retry never emails twice.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/idempotencyKey"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sent",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "type": "object",
                                            "required": [
                                                "ok",
                                                "data"
                                            ],
                                            "properties": {
                                                "ok": {
                                                    "const": true
                                                },
                                                "data": {
                                                    "$ref": "#/components/schemas/EstimateWritten"
                                                }
                                            }
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "sent": {
                                                    "$ref": "#/components/schemas/DocSent"
                                                }
                                            },
                                            "required": [
                                                "sent"
                                            ]
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/E400"
                    },
                    "404": {
                        "$ref": "#/components/responses/E404"
                    },
                    "409": {
                        "$ref": "#/components/responses/E409"
                    },
                    "422": {
                        "$ref": "#/components/responses/E422"
                    },
                    "502": {
                        "description": "send_failed: the message did not go out (nothing was charged or changed); retry later.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            }
        },
        "/invoices/{id}/send": {
            "parameters": [
                {
                    "name": "id",
                    "in": "path",
                    "required": true,
                    "description": "Invoice id.",
                    "schema": {
                        "type": "integer"
                    }
                }
            ],
            "post": {
                "tags": [
                    "Estimates & invoices"
                ],
                "operationId": "sendInvoice",
                "summary": "⚠️ Emails the invoice to its customer through the app's own send (letterhead email from your business, pay link when card or PayPal is on). No body.",
                "description": "As in the app, a sent invoice is marked finished (status unpaid). It is never marked paid. A paid invoice is 409 already_paid (no receipts from the API); emailed in the last 10 minutes is 409 recently_sent. Send an Idempotency-Key so a retry never emails twice.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/idempotencyKey"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Sent",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "type": "object",
                                            "required": [
                                                "ok",
                                                "data"
                                            ],
                                            "properties": {
                                                "ok": {
                                                    "const": true
                                                },
                                                "data": {
                                                    "$ref": "#/components/schemas/InvoiceWritten"
                                                }
                                            }
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "sent": {
                                                    "$ref": "#/components/schemas/DocSent"
                                                }
                                            },
                                            "required": [
                                                "sent"
                                            ]
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/E400"
                    },
                    "404": {
                        "$ref": "#/components/responses/E404"
                    },
                    "409": {
                        "$ref": "#/components/responses/E409"
                    },
                    "422": {
                        "$ref": "#/components/responses/E422"
                    },
                    "502": {
                        "description": "send_failed: the message did not go out (nothing was charged or changed); retry later.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            }
        },
        "/payments": {
            "get": {
                "tags": [
                    "Commerce"
                ],
                "operationId": "listPayments",
                "summary": "Money received, newest first (read-only). Plan: business_suite.",
                "parameters": [
                    {
                        "name": "since",
                        "in": "query",
                        "required": false,
                        "description": "Paid at or after. ISO 8601 (no offset = the business's local time), YYYY-MM-DD or unix seconds.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "until",
                        "in": "query",
                        "required": false,
                        "description": "Paid before (a date = the end of that day). ISO 8601 (no offset = the business's local time), YYYY-MM-DD or unix seconds.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "type",
                        "in": "query",
                        "required": false,
                        "description": "payment or deposit.",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "payment",
                                "deposit"
                            ]
                        }
                    },
                    {
                        "name": "method",
                        "in": "query",
                        "required": false,
                        "description": "One method.",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "cash",
                                "check",
                                "card",
                                "card_other",
                                "zelle",
                                "venmo",
                                "cashapp",
                                "paypal",
                                "split",
                                "other"
                            ]
                        }
                    },
                    {
                        "name": "invoice_id",
                        "in": "query",
                        "required": false,
                        "description": "Only this invoice's payments and deposits.",
                        "schema": {
                            "type": "integer"
                        }
                    },
                    {
                        "$ref": "#/components/parameters/limit"
                    },
                    {
                        "$ref": "#/components/parameters/cursor"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "data",
                                        "next_cursor",
                                        "limit"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "const": true
                                        },
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/Payment"
                                            }
                                        },
                                        "next_cursor": {
                                            "type": [
                                                "string",
                                                "null"
                                            ],
                                            "description": "Pass as `cursor` (with the same filters) for the next page; null on the last page."
                                        },
                                        "limit": {
                                            "type": "integer"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/E400"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            }
        },
        "/payments/{id}": {
            "parameters": [
                {
                    "name": "id",
                    "in": "path",
                    "required": true,
                    "description": "pay_s…, dep_s…, dep_c…, pay_q…, pay_k… or pay_v….",
                    "schema": {
                        "type": "string",
                        "pattern": "^(pay_s|dep_s|dep_c|pay_q|pay_k|pay_v)[1-9]\\d*$"
                    }
                }
            ],
            "get": {
                "tags": [
                    "Commerce"
                ],
                "operationId": "getPayment",
                "summary": "One payment.",
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "data"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "const": true
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/Payment"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/E404"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            }
        },
        "/quotes": {
            "get": {
                "tags": [
                    "Commerce"
                ],
                "operationId": "listQuotes",
                "summary": "Quote-builder quotes, newest first (read-only). Plan: quoting.",
                "parameters": [
                    {
                        "name": "status",
                        "in": "query",
                        "required": false,
                        "description": "One status.",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "quoted",
                                "viewed",
                                "expired",
                                "approved",
                                "install_pending",
                                "installed",
                                "declined"
                            ]
                        }
                    },
                    {
                        "name": "since",
                        "in": "query",
                        "required": false,
                        "description": "Created at or after. ISO 8601 (no offset = the business's local time), YYYY-MM-DD or unix seconds.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "until",
                        "in": "query",
                        "required": false,
                        "description": "Created before (a date = the end of that day). ISO 8601 (no offset = the business's local time), YYYY-MM-DD or unix seconds.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "$ref": "#/components/parameters/limit"
                    },
                    {
                        "$ref": "#/components/parameters/cursor"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "data",
                                        "next_cursor",
                                        "limit"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "const": true
                                        },
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/Quote"
                                            }
                                        },
                                        "next_cursor": {
                                            "type": [
                                                "string",
                                                "null"
                                            ],
                                            "description": "Pass as `cursor` (with the same filters) for the next page; null on the last page."
                                        },
                                        "limit": {
                                            "type": "integer"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/E400"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            }
        },
        "/quotes/{id}": {
            "parameters": [
                {
                    "name": "id",
                    "in": "path",
                    "required": true,
                    "description": "Quote id.",
                    "schema": {
                        "type": "integer"
                    }
                }
            ],
            "get": {
                "tags": [
                    "Commerce"
                ],
                "operationId": "getQuote",
                "summary": "One quote.",
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "data"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "const": true
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/Quote"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/E404"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            }
        },
        "/team": {
            "get": {
                "tags": [
                    "Operations"
                ],
                "operationId": "listTeam",
                "summary": "The business's people, by id (read-only). No plan gate.",
                "parameters": [
                    {
                        "name": "role",
                        "in": "query",
                        "required": false,
                        "description": "Comma-separated: owner, sales, tech, sales_tech.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "relationship",
                        "in": "query",
                        "required": false,
                        "description": "Comma-separated: owner, team_member, seat, crew.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "assignable",
                        "in": "query",
                        "required": false,
                        "description": "Only people a job can (true) or cannot (false) be handed to.",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "true",
                                "false"
                            ]
                        }
                    },
                    {
                        "name": "active",
                        "in": "query",
                        "required": false,
                        "description": "Active (true) or switched off (false).",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "true",
                                "false"
                            ]
                        }
                    },
                    {
                        "$ref": "#/components/parameters/limit"
                    },
                    {
                        "$ref": "#/components/parameters/cursor"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "data",
                                        "next_cursor",
                                        "limit"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "const": true
                                        },
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/TeamMember"
                                            }
                                        },
                                        "next_cursor": {
                                            "type": [
                                                "string",
                                                "null"
                                            ],
                                            "description": "Pass as `cursor` (with the same filters) for the next page; null on the last page."
                                        },
                                        "limit": {
                                            "type": "integer"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/E400"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            }
        },
        "/team/{id}": {
            "parameters": [
                {
                    "name": "id",
                    "in": "path",
                    "required": true,
                    "description": "Person id.",
                    "schema": {
                        "type": "integer"
                    }
                }
            ],
            "get": {
                "tags": [
                    "Operations"
                ],
                "operationId": "getTeamMember",
                "summary": "One person.",
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "data"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "const": true
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/TeamMember"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/E404"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            }
        },
        "/jobs": {
            "get": {
                "tags": [
                    "Operations"
                ],
                "operationId": "listJobs",
                "summary": "Jobs on the schedule, most recently changed first. Plan: business_suite.",
                "parameters": [
                    {
                        "name": "status",
                        "in": "query",
                        "required": false,
                        "description": "Comma-separated: unscheduled, scheduled, unconfirmed, confirmed, en_route, in_progress, completed, canceled, needs_reschedule.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "type",
                        "in": "query",
                        "required": false,
                        "description": "Comma-separated: install, service_booking, service_call, plan_visit, job.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "from",
                        "in": "query",
                        "required": false,
                        "description": "Start at or after. ISO 8601 (no offset = the business's local time), YYYY-MM-DD or unix seconds.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "to",
                        "in": "query",
                        "required": false,
                        "description": "Start before (a date = the end of that day). ISO 8601 (no offset = the business's local time), YYYY-MM-DD or unix seconds.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "tech_id",
                        "in": "query",
                        "required": false,
                        "description": "A person id from GET v1/team.",
                        "schema": {
                            "type": "integer",
                            "minimum": 1
                        }
                    },
                    {
                        "name": "customer_id",
                        "in": "query",
                        "required": false,
                        "description": "A cus_… id from GET v1/customers: every job on that customer's records.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "updated_since",
                        "in": "query",
                        "required": false,
                        "description": "Changed at or after. ISO 8601 (no offset = the business's local time), YYYY-MM-DD or unix seconds.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "$ref": "#/components/parameters/limit"
                    },
                    {
                        "$ref": "#/components/parameters/cursor"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "data",
                                        "next_cursor",
                                        "limit"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "const": true
                                        },
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/Job"
                                            }
                                        },
                                        "next_cursor": {
                                            "type": [
                                                "string",
                                                "null"
                                            ],
                                            "description": "Pass as `cursor` (with the same filters) for the next page; null on the last page."
                                        },
                                        "limit": {
                                            "type": "integer"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/E400"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            },
            "post": {
                "tags": [
                    "Operations"
                ],
                "operationId": "createJob",
                "summary": "Dispatch an install request to a tech (the app's Dispatch). The tech is notified in the app and by email and accepts or sends it back. Plan: business_suite + dispatch.",
                "description": "create_install_request(): the tech's hours and calendar are checked (409 tech_unavailable) and their stock (409 insufficient_stock; resend with \"force\": true). A job text goes out only when the business's job-assignment text template is approved and the tech opted in. Tech pay is never set.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/idempotencyKey"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/JobCreate"
                            }
                        },
                        "application/x-www-form-urlencoded": {
                            "schema": {
                                "$ref": "#/components/schemas/JobCreate"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Created (offer_status: pending)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "data"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "const": true
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/Job"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/E400"
                    },
                    "409": {
                        "$ref": "#/components/responses/E409"
                    },
                    "422": {
                        "$ref": "#/components/responses/E422"
                    },
                    "503": {
                        "$ref": "#/components/responses/E503"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            }
        },
        "/jobs/{id}": {
            "parameters": [
                {
                    "name": "id",
                    "in": "path",
                    "required": true,
                    "description": "ap_<id>.",
                    "schema": {
                        "type": "string",
                        "pattern": "^ap_[1-9]\\d*$"
                    }
                }
            ],
            "get": {
                "tags": [
                    "Operations"
                ],
                "operationId": "getJob",
                "summary": "One job (a sales consult's id is 404 here: it is a booking).",
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "data"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "const": true
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/Job"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/E404"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            },
            "patch": {
                "tags": [
                    "Operations"
                ],
                "operationId": "updateJob",
                "summary": "Move a job: a sold-deal install (its tech is offered the new time) or a customer's own service booking (customer-portal rules, the customer is emailed).",
                "description": "Any other job, and a completed or canceled one, is 409 not_changeable: move it on the Schedule board in FieldStacker.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/JobPatch"
                            }
                        },
                        "application/x-www-form-urlencoded": {
                            "schema": {
                                "$ref": "#/components/schemas/JobPatch"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "data"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "const": true
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/Job"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/E404"
                    },
                    "409": {
                        "$ref": "#/components/responses/E409"
                    },
                    "422": {
                        "$ref": "#/components/responses/E422"
                    },
                    "503": {
                        "$ref": "#/components/responses/E503"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            }
        },
        "/jobs/{id}/assign": {
            "parameters": [
                {
                    "name": "id",
                    "in": "path",
                    "required": true,
                    "description": "ap_<id>.",
                    "schema": {
                        "type": "string",
                        "pattern": "^ap_[1-9]\\d*$"
                    }
                }
            ],
            "post": {
                "tags": [
                    "Operations"
                ],
                "operationId": "assignJob",
                "summary": "Hand a sold install, or an install request its tech sent back, to another tech (offered to them). Plan: business_suite + dispatch.",
                "description": "Anything else is 409 not_changeable (reassign it on the Schedule board). The same tech again is 409 already_assigned. Tech pay is unchanged.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/idempotencyKey"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/JobAssign"
                            }
                        },
                        "application/x-www-form-urlencoded": {
                            "schema": {
                                "$ref": "#/components/schemas/JobAssign"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "data"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "const": true
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/Job"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/E400"
                    },
                    "404": {
                        "$ref": "#/components/responses/E404"
                    },
                    "409": {
                        "$ref": "#/components/responses/E409"
                    },
                    "422": {
                        "$ref": "#/components/responses/E422"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            }
        },
        "/service-plans": {
            "get": {
                "tags": [
                    "Operations"
                ],
                "operationId": "listServicePlans",
                "summary": "Service plans and recurring cleans, most recently changed first (read-only). Plan: business_suite.",
                "parameters": [
                    {
                        "name": "status",
                        "in": "query",
                        "required": false,
                        "description": "Comma-separated: active, paused, past_due, canceled, ended.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "type",
                        "in": "query",
                        "required": false,
                        "description": "Comma-separated: service_plan, cleaning_plan.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "updated_since",
                        "in": "query",
                        "required": false,
                        "description": "Changed at or after. ISO 8601 (no offset = the business's local time), YYYY-MM-DD or unix seconds.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "$ref": "#/components/parameters/limit"
                    },
                    {
                        "$ref": "#/components/parameters/cursor"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "data",
                                        "next_cursor",
                                        "limit"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "const": true
                                        },
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/ServicePlan"
                                            }
                                        },
                                        "next_cursor": {
                                            "type": [
                                                "string",
                                                "null"
                                            ],
                                            "description": "Pass as `cursor` (with the same filters) for the next page; null on the last page."
                                        },
                                        "limit": {
                                            "type": "integer"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/E400"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            }
        },
        "/service-plans/{id}": {
            "parameters": [
                {
                    "name": "id",
                    "in": "path",
                    "required": true,
                    "description": "sp_<id> or cp_<id>.",
                    "schema": {
                        "type": "string",
                        "pattern": "^(sp|cp)_[1-9]\\d*$"
                    }
                }
            ],
            "get": {
                "tags": [
                    "Operations"
                ],
                "operationId": "getServicePlan",
                "summary": "One plan with its latest 100 visits.",
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "data"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "const": true
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/ServicePlanDetail"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/E404"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            }
        },
        "/monitoring-accounts": {
            "get": {
                "tags": [
                    "Operations"
                ],
                "operationId": "listMonitoringAccounts",
                "summary": "The owner's alarm monitoring accounts, most recently changed first (read-only). Monitoring switched on (else 403 feature_off), then business_suite.",
                "parameters": [
                    {
                        "name": "status",
                        "in": "query",
                        "required": false,
                        "description": "Comma-separated: active, paused, canceled, ended.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "past_due",
                        "in": "query",
                        "required": false,
                        "description": "Only past-due (true) or not (false).",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "true",
                                "false"
                            ]
                        }
                    },
                    {
                        "name": "updated_since",
                        "in": "query",
                        "required": false,
                        "description": "Changed at or after. ISO 8601 (no offset = the business's local time), YYYY-MM-DD or unix seconds.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "$ref": "#/components/parameters/limit"
                    },
                    {
                        "$ref": "#/components/parameters/cursor"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "data",
                                        "next_cursor",
                                        "limit"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "const": true
                                        },
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/MonitoringAccount"
                                            }
                                        },
                                        "next_cursor": {
                                            "type": [
                                                "string",
                                                "null"
                                            ],
                                            "description": "Pass as `cursor` (with the same filters) for the next page; null on the last page."
                                        },
                                        "limit": {
                                            "type": "integer"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/E400"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            }
        },
        "/monitoring-accounts/{id}": {
            "parameters": [
                {
                    "name": "id",
                    "in": "path",
                    "required": true,
                    "description": "ma_<id>.",
                    "schema": {
                        "type": "string",
                        "pattern": "^ma_[1-9]\\d*$"
                    }
                }
            ],
            "get": {
                "tags": [
                    "Operations"
                ],
                "operationId": "getMonitoringAccount",
                "summary": "One monitoring account.",
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "data"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "const": true
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/MonitoringAccount"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/E404"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            }
        },
        "/schedule": {
            "get": {
                "tags": [
                    "Operations"
                ],
                "operationId": "getSchedule",
                "summary": "One calendar feed (jobs, appointments, online bookings, recurring-clean visits awaiting a date), by start time. Plan: the Schedule board or business_suite.",
                "parameters": [
                    {
                        "name": "from",
                        "in": "query",
                        "required": false,
                        "description": "Default: today. ISO 8601 (no offset = the business's local time), YYYY-MM-DD or unix seconds.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "to",
                        "in": "query",
                        "required": false,
                        "description": "Default: from + 7 days (a date = the end of that day). At most 92 days. ISO 8601 (no offset = the business's local time), YYYY-MM-DD or unix seconds.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "tech_id",
                        "in": "query",
                        "required": false,
                        "description": "A person id from GET v1/team.",
                        "schema": {
                            "type": "integer",
                            "minimum": 1
                        }
                    },
                    {
                        "name": "kind",
                        "in": "query",
                        "required": false,
                        "description": "Comma-separated: job, appointment, online_booking, plan_visit.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "include_canceled",
                        "in": "query",
                        "required": false,
                        "description": "true adds canceled and declined entries.",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "true",
                                "false"
                            ]
                        }
                    },
                    {
                        "$ref": "#/components/parameters/limit"
                    },
                    {
                        "$ref": "#/components/parameters/cursor"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "data",
                                        "next_cursor",
                                        "limit"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "const": true
                                        },
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/ScheduleEntry"
                                            }
                                        },
                                        "next_cursor": {
                                            "type": [
                                                "string",
                                                "null"
                                            ],
                                            "description": "Pass as `cursor` (with the same filters) for the next page; null on the last page."
                                        },
                                        "limit": {
                                            "type": "integer"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/E400"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            }
        },
        "/contracts": {
            "get": {
                "tags": [
                    "Documents & field records"
                ],
                "operationId": "listContracts",
                "summary": "E-sign contracts, most recently changed first. Plan: business_suite or quoting.",
                "parameters": [
                    {
                        "name": "status",
                        "in": "query",
                        "required": false,
                        "description": "One status.",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "draft",
                                "sent",
                                "viewed",
                                "signed",
                                "canceled"
                            ]
                        }
                    },
                    {
                        "name": "updated_since",
                        "in": "query",
                        "required": false,
                        "description": "Changed at or after. ISO 8601 (no offset = the business's local time), YYYY-MM-DD or unix seconds.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "$ref": "#/components/parameters/limit"
                    },
                    {
                        "$ref": "#/components/parameters/cursor"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "data",
                                        "next_cursor",
                                        "limit"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "const": true
                                        },
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/Contract"
                                            }
                                        },
                                        "next_cursor": {
                                            "type": [
                                                "string",
                                                "null"
                                            ],
                                            "description": "Pass as `cursor` (with the same filters) for the next page; null on the last page."
                                        },
                                        "limit": {
                                            "type": "integer"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/E400"
                    },
                    "503": {
                        "$ref": "#/components/responses/E503"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            },
            "post": {
                "tags": [
                    "Documents & field records"
                ],
                "operationId": "createContract",
                "summary": "Make a DRAFT contract from a template and one record (the app's New contract and its auto-fill). Nothing is sent.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/idempotencyKey"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/ContractCreate"
                            }
                        },
                        "application/x-www-form-urlencoded": {
                            "schema": {
                                "$ref": "#/components/schemas/ContractCreate"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Created",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "data"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "const": true
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/Contract"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/E400"
                    },
                    "409": {
                        "$ref": "#/components/responses/E409"
                    },
                    "422": {
                        "$ref": "#/components/responses/E422"
                    },
                    "503": {
                        "$ref": "#/components/responses/E503"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            }
        },
        "/contracts/{id}": {
            "parameters": [
                {
                    "name": "id",
                    "in": "path",
                    "required": true,
                    "description": "Contract id.",
                    "schema": {
                        "type": "integer"
                    }
                }
            ],
            "get": {
                "tags": [
                    "Documents & field records"
                ],
                "operationId": "getContract",
                "summary": "One contract.",
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "data"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "const": true
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/Contract"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/E404"
                    },
                    "503": {
                        "$ref": "#/components/responses/E503"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            }
        },
        "/contracts/{id}/send": {
            "parameters": [
                {
                    "name": "id",
                    "in": "path",
                    "required": true,
                    "description": "Contract id.",
                    "schema": {
                        "type": "integer"
                    }
                }
            ],
            "post": {
                "tags": [
                    "Documents & field records"
                ],
                "operationId": "sendContract",
                "summary": "⚠️ channel email messages your customer (the app's Email the link); channel link sends nothing and returns the signing link. Signing itself happens on the customer's own page.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/idempotencyKey"
                    }
                ],
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/ContractSend"
                            }
                        },
                        "application/x-www-form-urlencoded": {
                            "schema": {
                                "$ref": "#/components/schemas/ContractSend"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Sent (draft → sent)",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ContractSentAnswer"
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/E400"
                    },
                    "404": {
                        "$ref": "#/components/responses/E404"
                    },
                    "409": {
                        "$ref": "#/components/responses/E409"
                    },
                    "422": {
                        "$ref": "#/components/responses/E422"
                    },
                    "502": {
                        "description": "send_failed: the message did not go out (nothing was charged or changed); retry later.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "503": {
                        "$ref": "#/components/responses/E503"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            }
        },
        "/contract-templates": {
            "get": {
                "tags": [
                    "Documents & field records"
                ],
                "operationId": "listContractTemplates",
                "summary": "Your current contract templates, by id (read-only).",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/limit"
                    },
                    {
                        "$ref": "#/components/parameters/cursor"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "data",
                                        "next_cursor",
                                        "limit"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "const": true
                                        },
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/ContractTemplate"
                                            }
                                        },
                                        "next_cursor": {
                                            "type": [
                                                "string",
                                                "null"
                                            ],
                                            "description": "Pass as `cursor` (with the same filters) for the next page; null on the last page."
                                        },
                                        "limit": {
                                            "type": "integer"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/E400"
                    },
                    "503": {
                        "$ref": "#/components/responses/E503"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            }
        },
        "/documents": {
            "get": {
                "tags": [
                    "Documents & field records"
                ],
                "operationId": "listDocuments",
                "summary": "The Documents page (signed contracts), newest signed first (read-only).",
                "parameters": [
                    {
                        "name": "kind",
                        "in": "query",
                        "required": false,
                        "description": "contract.",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "contract"
                            ]
                        }
                    },
                    {
                        "name": "status",
                        "in": "query",
                        "required": false,
                        "description": "signed or canceled.",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "signed",
                                "canceled"
                            ]
                        }
                    },
                    {
                        "name": "from",
                        "in": "query",
                        "required": false,
                        "description": "Signed at or after. ISO 8601 (no offset = the business's local time), YYYY-MM-DD or unix seconds.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "to",
                        "in": "query",
                        "required": false,
                        "description": "Signed before (a date = the end of that day). ISO 8601 (no offset = the business's local time), YYYY-MM-DD or unix seconds.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "updated_since",
                        "in": "query",
                        "required": false,
                        "description": "Changed at or after. ISO 8601 (no offset = the business's local time), YYYY-MM-DD or unix seconds.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "$ref": "#/components/parameters/limit"
                    },
                    {
                        "$ref": "#/components/parameters/cursor"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "data",
                                        "next_cursor",
                                        "limit"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "const": true
                                        },
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/Document"
                                            }
                                        },
                                        "next_cursor": {
                                            "type": [
                                                "string",
                                                "null"
                                            ],
                                            "description": "Pass as `cursor` (with the same filters) for the next page; null on the last page."
                                        },
                                        "limit": {
                                            "type": "integer"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/E400"
                    },
                    "503": {
                        "$ref": "#/components/responses/E503"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            }
        },
        "/documents/{id}": {
            "parameters": [
                {
                    "name": "id",
                    "in": "path",
                    "required": true,
                    "description": "Document id.",
                    "schema": {
                        "type": "integer"
                    }
                }
            ],
            "get": {
                "tags": [
                    "Documents & field records"
                ],
                "operationId": "getDocument",
                "summary": "One document.",
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "data"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "const": true
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/Document"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/E404"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            }
        },
        "/notes": {
            "get": {
                "tags": [
                    "Documents & field records"
                ],
                "operationId": "listNotes",
                "summary": "A lead's or a customer's notes (send lead_id OR customer_id). Customer notes need a plan with Customers.",
                "parameters": [
                    {
                        "name": "lead_id",
                        "in": "query",
                        "required": false,
                        "description": "A lead (pin) id.",
                        "schema": {
                            "type": "integer",
                            "minimum": 1
                        }
                    },
                    {
                        "name": "customer_id",
                        "in": "query",
                        "required": false,
                        "description": "A cus_… id.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "$ref": "#/components/parameters/limit"
                    },
                    {
                        "$ref": "#/components/parameters/cursor"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/NotesAnswer"
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/E400"
                    },
                    "404": {
                        "$ref": "#/components/responses/E404"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            },
            "post": {
                "tags": [
                    "Documents & field records"
                ],
                "operationId": "createNote",
                "summary": "Add a line to a lead's or a customer's note, through the app's own save (a lead's History logs \"Note (API)\").",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/idempotencyKey"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/NoteCreate"
                            }
                        },
                        "application/x-www-form-urlencoded": {
                            "schema": {
                                "$ref": "#/components/schemas/NoteCreate"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Added",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/NotesAnswer"
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/E400"
                    },
                    "404": {
                        "$ref": "#/components/responses/E404"
                    },
                    "409": {
                        "$ref": "#/components/responses/E409"
                    },
                    "422": {
                        "$ref": "#/components/responses/E422"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            }
        },
        "/photos": {
            "get": {
                "tags": [
                    "Documents & field records"
                ],
                "operationId": "listPhotos",
                "summary": "Photo metadata, newest first (read-only). Pin photos need the knock map, job photos estimates and invoices; otherwise they are left out.",
                "parameters": [
                    {
                        "name": "source",
                        "in": "query",
                        "required": false,
                        "description": "media, pin or job.",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "media",
                                "pin",
                                "job"
                            ]
                        }
                    },
                    {
                        "name": "lead_id",
                        "in": "query",
                        "required": false,
                        "description": "",
                        "schema": {
                            "type": "integer",
                            "minimum": 1
                        }
                    },
                    {
                        "name": "job_id",
                        "in": "query",
                        "required": false,
                        "description": "An estimate / invoice id.",
                        "schema": {
                            "type": "integer",
                            "minimum": 1
                        }
                    },
                    {
                        "name": "since",
                        "in": "query",
                        "required": false,
                        "description": "Created after. ISO 8601 (no offset = the business's local time), YYYY-MM-DD or unix seconds.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "$ref": "#/components/parameters/limit"
                    },
                    {
                        "$ref": "#/components/parameters/cursor"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "data",
                                        "next_cursor",
                                        "limit"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "const": true
                                        },
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/Photo"
                                            }
                                        },
                                        "next_cursor": {
                                            "type": [
                                                "string",
                                                "null"
                                            ],
                                            "description": "Pass as `cursor` (with the same filters) for the next page; null on the last page."
                                        },
                                        "limit": {
                                            "type": "integer"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/E400"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            }
        },
        "/photos/{id}": {
            "parameters": [
                {
                    "name": "id",
                    "in": "path",
                    "required": true,
                    "description": "med_<id>, pin_<id> or job_<id>.",
                    "schema": {
                        "type": "string",
                        "pattern": "^(med|pin|job)_[1-9]\\d*$"
                    }
                }
            ],
            "get": {
                "tags": [
                    "Documents & field records"
                ],
                "operationId": "getPhoto",
                "summary": "One photo's metadata.",
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "data"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "const": true
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/Photo"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/E404"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            }
        },
        "/reviews": {
            "get": {
                "tags": [
                    "Documents & field records"
                ],
                "operationId": "listReviews",
                "summary": "Star reviews on your digital cards, newest first (read-only).",
                "parameters": [
                    {
                        "name": "since",
                        "in": "query",
                        "required": false,
                        "description": "Created after. ISO 8601 (no offset = the business's local time), YYYY-MM-DD or unix seconds.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "min_rating",
                        "in": "query",
                        "required": false,
                        "description": "1–5.",
                        "schema": {
                            "type": "integer",
                            "minimum": 1,
                            "maximum": 5
                        }
                    },
                    {
                        "name": "hidden",
                        "in": "query",
                        "required": false,
                        "description": "Only hidden (true) or shown (false) reviews.",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "true",
                                "false"
                            ]
                        }
                    },
                    {
                        "$ref": "#/components/parameters/limit"
                    },
                    {
                        "$ref": "#/components/parameters/cursor"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "data",
                                        "next_cursor",
                                        "limit"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "const": true
                                        },
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/Review"
                                            }
                                        },
                                        "next_cursor": {
                                            "type": [
                                                "string",
                                                "null"
                                            ],
                                            "description": "Pass as `cursor` (with the same filters) for the next page; null on the last page."
                                        },
                                        "limit": {
                                            "type": "integer"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/E400"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            }
        },
        "/reviews/{id}": {
            "parameters": [
                {
                    "name": "id",
                    "in": "path",
                    "required": true,
                    "description": "Review id.",
                    "schema": {
                        "type": "integer"
                    }
                }
            ],
            "get": {
                "tags": [
                    "Documents & field records"
                ],
                "operationId": "getReview",
                "summary": "One review.",
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "data"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "const": true
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/Review"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/E404"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            }
        },
        "/knocks": {
            "get": {
                "tags": [
                    "Documents & field records"
                ],
                "operationId": "listKnocks",
                "summary": "Door-knock history (worked doors), most recently changed first (read-only). Plan: the knock map.",
                "parameters": [
                    {
                        "name": "from",
                        "in": "query",
                        "required": false,
                        "description": "Knocked at or after. ISO 8601 (no offset = the business's local time), YYYY-MM-DD or unix seconds.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "to",
                        "in": "query",
                        "required": false,
                        "description": "Knocked before (a date = the end of that day). ISO 8601 (no offset = the business's local time), YYYY-MM-DD or unix seconds.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "updated_since",
                        "in": "query",
                        "required": false,
                        "description": "Changed at or after. ISO 8601 (no offset = the business's local time), YYYY-MM-DD or unix seconds.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "status",
                        "in": "query",
                        "required": false,
                        "description": "One disposition key.",
                        "schema": {
                            "type": "string",
                            "pattern": "^[a-z0-9_]{1,24}$"
                        }
                    },
                    {
                        "name": "rep_id",
                        "in": "query",
                        "required": false,
                        "description": "Who knocked it.",
                        "schema": {
                            "type": "integer",
                            "minimum": 1
                        }
                    },
                    {
                        "$ref": "#/components/parameters/limit"
                    },
                    {
                        "$ref": "#/components/parameters/cursor"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "data",
                                        "next_cursor",
                                        "limit"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "const": true
                                        },
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/Knock"
                                            }
                                        },
                                        "next_cursor": {
                                            "type": [
                                                "string",
                                                "null"
                                            ],
                                            "description": "Pass as `cursor` (with the same filters) for the next page; null on the last page."
                                        },
                                        "limit": {
                                            "type": "integer"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/E400"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            }
        },
        "/knocks/{id}": {
            "parameters": [
                {
                    "name": "id",
                    "in": "path",
                    "required": true,
                    "description": "Pin id.",
                    "schema": {
                        "type": "integer"
                    }
                }
            ],
            "get": {
                "tags": [
                    "Documents & field records"
                ],
                "operationId": "getKnock",
                "summary": "One worked door with its visits.",
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "data"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "const": true
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/KnockDetail"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/E404"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            }
        },
        "/campaigns": {
            "get": {
                "tags": [
                    "Documents & field records"
                ],
                "operationId": "listCampaigns",
                "summary": "Marketing campaigns with counts, most recently changed first (read-only). Plan: the marketing suite.",
                "parameters": [
                    {
                        "name": "status",
                        "in": "query",
                        "required": false,
                        "description": "One status.",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "active",
                                "paused",
                                "draft",
                                "archived"
                            ]
                        }
                    },
                    {
                        "name": "updated_since",
                        "in": "query",
                        "required": false,
                        "description": "Changed at or after. ISO 8601 (no offset = the business's local time), YYYY-MM-DD or unix seconds.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "$ref": "#/components/parameters/limit"
                    },
                    {
                        "$ref": "#/components/parameters/cursor"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "data",
                                        "next_cursor",
                                        "limit"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "const": true
                                        },
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/Campaign"
                                            }
                                        },
                                        "next_cursor": {
                                            "type": [
                                                "string",
                                                "null"
                                            ],
                                            "description": "Pass as `cursor` (with the same filters) for the next page; null on the last page."
                                        },
                                        "limit": {
                                            "type": "integer"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/E400"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            }
        },
        "/campaigns/summary": {
            "get": {
                "tags": [
                    "Documents & field records"
                ],
                "operationId": "getCampaignSummary",
                "summary": "Your marketing in one answer: campaigns, direct mail, lit-up postcards.",
                "parameters": [
                    {
                        "name": "from",
                        "in": "query",
                        "required": false,
                        "description": "At or after. ISO 8601 (no offset = the business's local time), YYYY-MM-DD or unix seconds.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "to",
                        "in": "query",
                        "required": false,
                        "description": "Before (a date = the end of that day). ISO 8601 (no offset = the business's local time), YYYY-MM-DD or unix seconds.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "data"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "const": true
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/CampaignSummary"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/E400"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            }
        },
        "/campaigns/{id}": {
            "parameters": [
                {
                    "name": "id",
                    "in": "path",
                    "required": true,
                    "description": "Campaign id.",
                    "schema": {
                        "type": "integer"
                    }
                }
            ],
            "get": {
                "tags": [
                    "Documents & field records"
                ],
                "operationId": "getCampaign",
                "summary": "One campaign.",
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "data"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "const": true
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/Campaign"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/E404"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "500": {
                        "$ref": "#/components/responses/E500"
                    }
                }
            }
        }
    },
    "components": {
        "securitySchemes": {
            "bearerAuth": {
                "type": "http",
                "scheme": "bearer",
                "description": "Authorization: Bearer fsk_… (Settings → API & webhooks). Never put the key in the URL (400 key_in_url)."
            },
            "apiKeyHeader": {
                "type": "apiKey",
                "in": "header",
                "name": "X-API-Key"
            }
        },
        "schemas": {
            "Error": {
                "type": "object",
                "properties": {
                    "ok": {
                        "const": false
                    },
                    "error": {
                        "type": "object",
                        "properties": {
                            "code": {
                                "type": "string",
                                "description": "Machine-readable, e.g. bad_email, not_found, plan_required."
                            },
                            "message": {
                                "type": "string",
                                "description": "For a person."
                            },
                            "field": {
                                "type": [
                                    "string",
                                    "null"
                                ],
                                "description": "The field at fault, or null. Absent on the older leads routes."
                            }
                        },
                        "required": [
                            "code",
                            "message"
                        ]
                    }
                },
                "required": [
                    "ok",
                    "error"
                ]
            },
            "Me": {
                "type": "object",
                "properties": {
                    "ok": {
                        "const": true
                    },
                    "company_id": {
                        "type": "integer"
                    },
                    "company_name": {
                        "type": "string"
                    },
                    "owner_name": {
                        "type": "string"
                    },
                    "timezone": {
                        "type": "string",
                        "description": "IANA zone, e.g. America/Los_Angeles."
                    },
                    "api_version": {
                        "type": "string",
                        "examples": [
                            "2026-10-16"
                        ]
                    },
                    "events": {
                        "type": "array",
                        "items": {
                            "type": "string"
                        },
                        "description": "Every webhook event key (GET v1/events has names and descriptions)."
                    }
                },
                "required": [
                    "ok",
                    "company_id",
                    "company_name",
                    "owner_name",
                    "timezone",
                    "api_version",
                    "events"
                ]
            },
            "Lead": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "integer"
                    },
                    "rep_id": {
                        "type": [
                            "integer",
                            "null"
                        ],
                        "description": "The rep the pin belongs to (assigned rep, else its owner)."
                    },
                    "rep_name": {
                        "type": "string"
                    },
                    "rep_email": {
                        "type": "string"
                    },
                    "lead_id": {
                        "type": "integer",
                        "description": "Same as id."
                    },
                    "lead_name": {
                        "type": "string"
                    },
                    "lead_business_name": {
                        "type": "string",
                        "description": "Set when the pin is a business."
                    },
                    "lead_contact_name": {
                        "type": "string"
                    },
                    "lead_contact_position": {
                        "type": "string"
                    },
                    "lead_phone": {
                        "type": "string"
                    },
                    "lead_email": {
                        "type": "string"
                    },
                    "lead_address": {
                        "type": "string"
                    },
                    "lead_lat": {
                        "type": [
                            "number",
                            "null"
                        ]
                    },
                    "lead_lng": {
                        "type": [
                            "number",
                            "null"
                        ]
                    },
                    "lead_status": {
                        "type": "string",
                        "description": "The disposition key."
                    },
                    "lead_status_label": {
                        "type": "string",
                        "description": "The business's own label for it."
                    },
                    "lead_notes": {
                        "type": "string",
                        "description": "Cut to 300 characters."
                    },
                    "lead_source": {
                        "type": "string",
                        "description": "map, import, api, appointment, …"
                    },
                    "lead_category": {
                        "type": "string"
                    },
                    "lead_is_business": {
                        "type": "boolean"
                    },
                    "lead_created_at": {
                        "type": "string",
                        "description": "ISO 8601 UTC (\"…Z\")."
                    },
                    "lead_url": {
                        "type": "string",
                        "description": "Opens the pin in FieldStacker."
                    }
                },
                "required": [
                    "id",
                    "lead_id",
                    "lead_name",
                    "lead_status",
                    "lead_created_at"
                ],
                "description": "A lead (map pin): the flat fields every lead webhook carries. Numbers are numbers here (the older shape)."
            },
            "LeadCreate": {
                "type": "object",
                "properties": {
                    "name": {
                        "type": "string",
                        "maxLength": 120
                    },
                    "business_name": {
                        "type": "string",
                        "description": "Makes the pin a business.",
                        "maxLength": 120
                    },
                    "contact_name": {
                        "type": "string",
                        "maxLength": 120
                    },
                    "position": {
                        "type": "string",
                        "maxLength": 80
                    },
                    "phone": {
                        "type": "string",
                        "maxLength": 40
                    },
                    "email": {
                        "type": "string",
                        "maxLength": 255,
                        "format": "email"
                    },
                    "address": {
                        "type": "string",
                        "description": "Geocoded when lat/lng are not sent (cache first, then one lookup under the owner's daily cap).",
                        "maxLength": 255
                    },
                    "lat": {
                        "type": "number",
                        "minimum": -90,
                        "maximum": 90
                    },
                    "lng": {
                        "type": "number",
                        "minimum": -180,
                        "maximum": 180
                    },
                    "notes": {
                        "type": "string",
                        "maxLength": 500
                    },
                    "category": {
                        "type": "string",
                        "maxLength": 60
                    },
                    "status": {
                        "type": "string",
                        "description": "A disposition key or label (default lead)."
                    },
                    "assign_to": {
                        "type": "string",
                        "description": "A teammate's email.",
                        "format": "email"
                    },
                    "external_id": {
                        "type": "string",
                        "description": "Your id: the same one again returns the first lead with duplicate: true.",
                        "maxLength": 100
                    },
                    "notify_webhooks": {
                        "type": "boolean",
                        "default": true,
                        "description": "false = do not fire lead.created (avoids loops)."
                    }
                },
                "description": "Send at least one of name, business_name, phone, email, address — and an address or lat + lng."
            },
            "LeadPatch": {
                "type": "object",
                "properties": {
                    "status": {
                        "type": "string",
                        "description": "A disposition key or label."
                    },
                    "notes": {
                        "type": "string",
                        "description": "Replaces the notes.",
                        "maxLength": 500
                    },
                    "append_note": {
                        "type": "string",
                        "description": "Adds a line."
                    }
                }
            },
            "LeadAnswer": {
                "type": "object",
                "properties": {
                    "ok": {
                        "const": true
                    },
                    "duplicate": {
                        "type": "boolean",
                        "description": "Present (true) when external_id / Idempotency-Key matched an existing lead."
                    },
                    "lead": {
                        "$ref": "#/components/schemas/Lead"
                    }
                },
                "required": [
                    "ok",
                    "lead"
                ]
            },
            "Customer": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "cus_ + kind letter + record id (q quote, c card contact, s estimate/invoice, a appointment, k won door). The OLDEST record's id.",
                        "pattern": "^cus_[qcsak][1-9]\\d*$"
                    },
                    "name": {
                        "type": "string"
                    },
                    "business": {
                        "type": "string"
                    },
                    "phone": {
                        "type": "string"
                    },
                    "alt_phone": {
                        "type": "string"
                    },
                    "email": {
                        "type": "string"
                    },
                    "address": {
                        "type": "string"
                    },
                    "tags": {
                        "type": "array",
                        "items": {
                            "type": "string"
                        }
                    },
                    "notes": {
                        "type": "string"
                    },
                    "record_ids": {
                        "type": "array",
                        "items": {
                            "type": "string"
                        },
                        "maxItems": 50,
                        "description": "Every one resolves to this customer."
                    },
                    "records": {
                        "type": "object",
                        "properties": {
                            "quotes": {
                                "type": "integer"
                            },
                            "card_contacts": {
                                "type": "integer"
                            },
                            "estimates_and_invoices": {
                                "type": "integer"
                            },
                            "appointments": {
                                "type": "integer"
                            },
                            "doors": {
                                "type": "integer",
                                "description": "Door trades only."
                            }
                        },
                        "required": [
                            "quotes",
                            "card_contacts",
                            "estimates_and_invoices",
                            "appointments"
                        ]
                    },
                    "created_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 with the business's UTC offset."
                    },
                    "updated_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "Last activity or edit. ISO 8601 with the business's UTC offset."
                    }
                },
                "required": [
                    "id",
                    "name",
                    "business",
                    "phone",
                    "alt_phone",
                    "email",
                    "address",
                    "tags",
                    "notes",
                    "record_ids",
                    "records",
                    "created_at",
                    "updated_at"
                ],
                "description": "A customer, built from their records. Gate codes (access_notes) are never returned."
            },
            "CustomerCreate": {
                "type": "object",
                "properties": {
                    "name": {
                        "type": "string",
                        "maxLength": 120
                    },
                    "phone": {
                        "type": "string",
                        "maxLength": 40
                    },
                    "email": {
                        "type": "string",
                        "maxLength": 160,
                        "format": "email"
                    },
                    "address": {
                        "type": "string",
                        "maxLength": 300
                    },
                    "notes": {
                        "type": "string",
                        "maxLength": 500
                    },
                    "lat": {
                        "type": "number",
                        "minimum": -90,
                        "maximum": 90
                    },
                    "lng": {
                        "type": "number",
                        "minimum": -180,
                        "maximum": 180
                    }
                },
                "description": "At least one of name, phone, email. lat and lng go together."
            },
            "CustomerPatch": {
                "type": "object",
                "properties": {
                    "name": {
                        "type": "string",
                        "maxLength": 120
                    },
                    "business": {
                        "type": "string",
                        "maxLength": 120
                    },
                    "phone": {
                        "type": "string",
                        "maxLength": 40
                    },
                    "alt_phone": {
                        "type": "string",
                        "maxLength": 40
                    },
                    "email": {
                        "type": "string",
                        "maxLength": 160
                    },
                    "address": {
                        "type": "string",
                        "maxLength": 300
                    },
                    "notes": {
                        "type": "string",
                        "maxLength": 4000
                    },
                    "tags": {
                        "oneOf": [
                            {
                                "type": "string",
                                "maxLength": 200
                            },
                            {
                                "type": "array",
                                "items": {
                                    "type": "string"
                                }
                            }
                        ]
                    }
                },
                "description": "Only the fields sent change (what FieldStacker shows for the customer; past documents keep what was on them)."
            },
            "Booking": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string",
                        "description": "bk_<id> online booking, ap_<id> schedule appointment.",
                        "pattern": "^(bk|ap)_[1-9]\\d*$"
                    },
                    "type": {
                        "type": "string",
                        "enum": [
                            "online_booking",
                            "appointment"
                        ]
                    },
                    "status": {
                        "type": "string",
                        "enum": [
                            "pending",
                            "confirmed",
                            "canceled",
                            "declined",
                            "completed",
                            "no_show"
                        ]
                    },
                    "title": {
                        "type": "string"
                    },
                    "service": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "The booking page service key (online bookings only)."
                    },
                    "start_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 with the business's UTC offset."
                    },
                    "end_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 with the business's UTC offset."
                    },
                    "duration_min": {
                        "type": [
                            "integer",
                            "null"
                        ]
                    },
                    "timezone": {
                        "type": "string"
                    },
                    "customer": {
                        "type": "object",
                        "properties": {
                            "name": {
                                "type": "string"
                            },
                            "phone": {
                                "type": "string"
                            },
                            "email": {
                                "type": "string"
                            },
                            "address": {
                                "type": "string"
                            }
                        },
                        "required": [
                            "name",
                            "phone",
                            "email",
                            "address"
                        ]
                    },
                    "notes": {
                        "type": "string"
                    },
                    "job_number": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Schedule appointments only."
                    },
                    "changeable": {
                        "type": "boolean",
                        "description": "true = PATCH may move / cancel it."
                    },
                    "created_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 with the business's UTC offset."
                    },
                    "confirmed_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 with the business's UTC offset."
                    },
                    "canceled_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 with the business's UTC offset."
                    }
                },
                "required": [
                    "id",
                    "type",
                    "status",
                    "title",
                    "service",
                    "start_at",
                    "end_at",
                    "duration_min",
                    "timezone",
                    "customer",
                    "notes",
                    "job_number",
                    "changeable",
                    "created_at",
                    "confirmed_at",
                    "canceled_at"
                ],
                "description": "Manage tokens, calendar ids, tech pay, fees and mileage are never returned."
            },
            "BookingCustomerIn": {
                "type": "object",
                "properties": {
                    "name": {
                        "type": "string",
                        "maxLength": 120
                    },
                    "email": {
                        "type": "string",
                        "maxLength": 160,
                        "format": "email"
                    },
                    "phone": {
                        "type": "string",
                        "maxLength": 40
                    },
                    "address": {
                        "type": "string",
                        "maxLength": 300
                    },
                    "notes": {
                        "type": "string",
                        "maxLength": 1000
                    },
                    "answers": {
                        "type": "object",
                        "additionalProperties": {
                            "type": "string",
                            "maxLength": 1000
                        },
                        "description": "Intake question key → answer (GET v1/availability lists the questions)."
                    }
                },
                "required": [
                    "name"
                ]
            },
            "BookingCreate": {
                "type": "object",
                "properties": {
                    "start_at": {
                        "type": "string",
                        "description": "One of the open times from GET v1/availability (a date alone is refused).",
                        "format": "date-time"
                    },
                    "service": {
                        "type": "string",
                        "description": "A service key from GET v1/availability.",
                        "maxLength": 60
                    },
                    "customer": {
                        "$ref": "#/components/schemas/BookingCustomerIn"
                    }
                },
                "required": [
                    "start_at",
                    "customer"
                ],
                "description": "The customer fields may also be sent flat (name, email, phone, address, notes, answers). Name plus an email or phone is required."
            },
            "BookingPatch": {
                "type": "object",
                "properties": {
                    "start_at": {
                        "type": "string",
                        "description": "Move it (an open time).",
                        "format": "date-time"
                    },
                    "status": {
                        "type": "string",
                        "enum": [
                            "canceled",
                            "confirmed"
                        ]
                    }
                },
                "description": "Send start_at or status (not start_at with canceled)."
            },
            "Availability": {
                "type": "object",
                "properties": {
                    "enabled": {
                        "type": "boolean",
                        "description": "Online booking is on."
                    },
                    "needs_approval": {
                        "type": "boolean"
                    },
                    "timezone": {
                        "type": "string"
                    },
                    "duration_min": {
                        "type": "integer"
                    },
                    "services": {
                        "type": "array",
                        "items": {
                            "type": "object",
                            "properties": {
                                "key": {
                                    "type": "string"
                                },
                                "label": {
                                    "type": "string"
                                }
                            },
                            "required": [
                                "key",
                                "label"
                            ]
                        }
                    },
                    "questions": {
                        "type": "array",
                        "items": {
                            "type": "object",
                            "properties": {
                                "key": {
                                    "type": "string"
                                },
                                "label": {
                                    "type": "string"
                                },
                                "type": {
                                    "type": "string"
                                },
                                "required": {
                                    "type": "boolean"
                                },
                                "options": {
                                    "type": "array",
                                    "items": {
                                        "type": "string"
                                    }
                                }
                            },
                            "required": [
                                "key",
                                "label",
                                "type",
                                "required"
                            ]
                        }
                    },
                    "dates": {
                        "type": "array",
                        "items": {
                            "type": "string",
                            "format": "date"
                        },
                        "description": "Without ?date: the next days with an open time (≤30)."
                    },
                    "date": {
                        "type": "string",
                        "format": "date",
                        "description": "With ?date."
                    },
                    "slots": {
                        "type": "array",
                        "description": "With ?date: the open start times.",
                        "items": {
                            "type": "object",
                            "properties": {
                                "start_at": {
                                    "type": [
                                        "string",
                                        "null"
                                    ],
                                    "format": "date-time",
                                    "description": "ISO 8601 with the business's UTC offset."
                                },
                                "end_at": {
                                    "type": [
                                        "string",
                                        "null"
                                    ],
                                    "format": "date-time",
                                    "description": "ISO 8601 with the business's UTC offset."
                                },
                                "label": {
                                    "type": "string"
                                }
                            },
                            "required": [
                                "start_at",
                                "end_at",
                                "label"
                            ]
                        }
                    }
                },
                "required": [
                    "enabled",
                    "needs_approval",
                    "timezone",
                    "duration_min",
                    "services",
                    "questions"
                ]
            },
            "DocLine": {
                "type": "object",
                "properties": {
                    "name": {
                        "type": "string"
                    },
                    "quantity": {
                        "type": "string",
                        "description": "Decimal string without trailing zeros (\"2\", \"2.5\")."
                    },
                    "unit_price": {
                        "type": "string",
                        "pattern": "^-?\\d+\\.\\d{2}$",
                        "examples": [
                            "1250.00"
                        ]
                    },
                    "amount": {
                        "type": "string",
                        "pattern": "^-?\\d+\\.\\d{2}$",
                        "examples": [
                            "1250.00"
                        ]
                    },
                    "discount": {
                        "type": "object",
                        "properties": {
                            "type": {
                                "type": "string",
                                "enum": [
                                    "percent",
                                    "amount_per_unit"
                                ]
                            },
                            "value": {
                                "type": "string",
                                "pattern": "^-?\\d+\\.\\d{2}$",
                                "examples": [
                                    "1250.00"
                                ]
                            },
                            "amount_off": {
                                "type": "string",
                                "pattern": "^-?\\d+\\.\\d{2}$",
                                "examples": [
                                    "1250.00"
                                ]
                            },
                            "note": {
                                "type": "string"
                            }
                        },
                        "required": [
                            "type",
                            "value",
                            "amount_off",
                            "note"
                        ],
                        "description": "Present only on a line with a customer-visible discount."
                    }
                },
                "required": [
                    "name",
                    "quantity",
                    "unit_price",
                    "amount"
                ],
                "description": "Customer-hidden (commission) lines are never returned."
            },
            "Estimate": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "integer"
                    },
                    "number": {
                        "type": "string"
                    },
                    "type": {
                        "type": "string",
                        "enum": [
                            "estimate",
                            "invoice"
                        ]
                    },
                    "customer": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": [
                                    "string",
                                    "null"
                                ],
                                "description": "cus_s<id>: the customer this document belongs to (GET v1/customers/{id})."
                            },
                            "name": {
                                "type": "string"
                            },
                            "contact_name": {
                                "type": "string"
                            },
                            "phone": {
                                "type": "string"
                            },
                            "email": {
                                "type": "string"
                            },
                            "address": {
                                "type": "string"
                            }
                        },
                        "required": [
                            "id",
                            "name",
                            "contact_name",
                            "phone",
                            "email",
                            "address"
                        ]
                    },
                    "lines": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/DocLine"
                        }
                    },
                    "currency": {
                        "type": "string",
                        "examples": [
                            "USD"
                        ]
                    },
                    "subtotal": {
                        "type": "string",
                        "pattern": "^-?\\d+\\.\\d{2}$",
                        "examples": [
                            "1250.00"
                        ]
                    },
                    "labor": {
                        "type": "string",
                        "pattern": "^-?\\d+\\.\\d{2}$",
                        "examples": [
                            "1250.00"
                        ]
                    },
                    "tax_rate": {
                        "type": "string",
                        "description": "Percent, e.g. \"8.25\"."
                    },
                    "tax": {
                        "type": "string",
                        "pattern": "^-?\\d+\\.\\d{2}$",
                        "examples": [
                            "1250.00"
                        ]
                    },
                    "total": {
                        "type": "string",
                        "pattern": "^-?\\d+\\.\\d{2}$",
                        "examples": [
                            "1250.00"
                        ]
                    },
                    "notes": {
                        "type": "string"
                    },
                    "customer_url": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "The document's existing share link (never created by the API)."
                    },
                    "created_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 with the business's UTC offset."
                    },
                    "updated_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 with the business's UTC offset."
                    },
                    "sent_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 with the business's UTC offset."
                    },
                    "status": {
                        "type": "string",
                        "enum": [
                            "draft",
                            "sent",
                            "approved"
                        ]
                    },
                    "approved_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 with the business's UTC offset."
                    }
                },
                "required": [
                    "id",
                    "number",
                    "type",
                    "status",
                    "customer",
                    "lines",
                    "currency",
                    "subtotal",
                    "labor",
                    "tax_rate",
                    "tax",
                    "total",
                    "notes",
                    "customer_url",
                    "created_at",
                    "updated_at",
                    "sent_at",
                    "approved_at"
                ],
                "description": "Never returned: cost, profit, commission, fees, the pay token, payment intents."
            },
            "Invoice": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "integer"
                    },
                    "number": {
                        "type": "string"
                    },
                    "type": {
                        "type": "string",
                        "enum": [
                            "estimate",
                            "invoice"
                        ]
                    },
                    "customer": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": [
                                    "string",
                                    "null"
                                ],
                                "description": "cus_s<id>: the customer this document belongs to (GET v1/customers/{id})."
                            },
                            "name": {
                                "type": "string"
                            },
                            "contact_name": {
                                "type": "string"
                            },
                            "phone": {
                                "type": "string"
                            },
                            "email": {
                                "type": "string"
                            },
                            "address": {
                                "type": "string"
                            }
                        },
                        "required": [
                            "id",
                            "name",
                            "contact_name",
                            "phone",
                            "email",
                            "address"
                        ]
                    },
                    "lines": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/DocLine"
                        }
                    },
                    "currency": {
                        "type": "string",
                        "examples": [
                            "USD"
                        ]
                    },
                    "subtotal": {
                        "type": "string",
                        "pattern": "^-?\\d+\\.\\d{2}$",
                        "examples": [
                            "1250.00"
                        ]
                    },
                    "labor": {
                        "type": "string",
                        "pattern": "^-?\\d+\\.\\d{2}$",
                        "examples": [
                            "1250.00"
                        ]
                    },
                    "tax_rate": {
                        "type": "string",
                        "description": "Percent, e.g. \"8.25\"."
                    },
                    "tax": {
                        "type": "string",
                        "pattern": "^-?\\d+\\.\\d{2}$",
                        "examples": [
                            "1250.00"
                        ]
                    },
                    "total": {
                        "type": "string",
                        "pattern": "^-?\\d+\\.\\d{2}$",
                        "examples": [
                            "1250.00"
                        ]
                    },
                    "notes": {
                        "type": "string"
                    },
                    "customer_url": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "The document's existing share link (never created by the API)."
                    },
                    "created_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 with the business's UTC offset."
                    },
                    "updated_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 with the business's UTC offset."
                    },
                    "sent_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 with the business's UTC offset."
                    },
                    "status": {
                        "type": "string",
                        "enum": [
                            "draft",
                            "in_progress",
                            "sent",
                            "unpaid",
                            "paid"
                        ]
                    },
                    "invoice_date": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date"
                    },
                    "due_date": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date"
                    },
                    "amount_paid": {
                        "type": "string",
                        "pattern": "^-?\\d+\\.\\d{2}$",
                        "examples": [
                            "1250.00"
                        ]
                    },
                    "deposit_paid": {
                        "type": "string",
                        "pattern": "^-?\\d+\\.\\d{2}$",
                        "examples": [
                            "1250.00"
                        ]
                    },
                    "paid_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 with the business's UTC offset."
                    },
                    "payment_method": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "e.g. Cash, Card."
                    },
                    "completed_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 with the business's UTC offset."
                    }
                },
                "required": [
                    "id",
                    "number",
                    "type",
                    "status",
                    "customer",
                    "lines",
                    "currency",
                    "subtotal",
                    "labor",
                    "tax_rate",
                    "tax",
                    "total",
                    "notes",
                    "customer_url",
                    "created_at",
                    "updated_at",
                    "sent_at",
                    "invoice_date",
                    "due_date",
                    "amount_paid",
                    "deposit_paid",
                    "paid_at",
                    "payment_method",
                    "completed_at"
                ],
                "description": "Never returned: cost, profit, commission, fees, the pay token, payment intents, card or bank data."
            },
            "Service": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "integer"
                    },
                    "key": {
                        "type": "string"
                    },
                    "name": {
                        "type": "string"
                    },
                    "model": {
                        "type": "string"
                    },
                    "category": {
                        "type": "string"
                    },
                    "price": {
                        "type": "string",
                        "pattern": "^-?\\d+\\.\\d{2}$",
                        "examples": [
                            "1250.00"
                        ]
                    },
                    "currency": {
                        "type": "string"
                    },
                    "shown_on_website": {
                        "type": "boolean"
                    }
                },
                "required": [
                    "id",
                    "key",
                    "name",
                    "model",
                    "category",
                    "price",
                    "currency",
                    "shown_on_website"
                ],
                "description": "A price-list item. Cost, labor cost and pass-through cost are never returned."
            },
            "FormLead": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string",
                        "description": "msg_<id> | lp_<id> | card_<id>",
                        "pattern": "^(msg|lp|card)_[1-9]\\d*$"
                    },
                    "source": {
                        "type": "string",
                        "enum": [
                            "website_message",
                            "website_form",
                            "landing_page",
                            "card"
                        ]
                    },
                    "name": {
                        "type": "string"
                    },
                    "email": {
                        "type": "string"
                    },
                    "phone": {
                        "type": "string"
                    },
                    "address": {
                        "type": "string"
                    },
                    "message": {
                        "type": "string"
                    },
                    "campaign_id": {
                        "type": [
                            "integer",
                            "null"
                        ]
                    },
                    "customer_id": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "The customer the lead became (null for website messages)."
                    },
                    "created_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 with the business's UTC offset."
                    }
                },
                "required": [
                    "id",
                    "source",
                    "name",
                    "email",
                    "phone",
                    "address",
                    "message",
                    "campaign_id",
                    "customer_id",
                    "created_at"
                ]
            },
            "Webhook": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "integer"
                    },
                    "label": {
                        "type": "string"
                    },
                    "url": {
                        "type": "string",
                        "description": "https on a public host.",
                        "format": "uri"
                    },
                    "events": {
                        "type": "array",
                        "items": {
                            "type": "string",
                            "enum": [
                                "lead.created",
                                "lead.status_changed",
                                "lead.sold",
                                "appointment.created",
                                "quote.approved",
                                "invoice.paid",
                                "booking.requested",
                                "booking.rescheduled",
                                "booking.canceled",
                                "website.form",
                                "campaign.lead",
                                "chat.lead",
                                "card.lead",
                                "review.received",
                                "lighting.reply",
                                "lighting.postcard_opened"
                            ]
                        }
                    },
                    "status": {
                        "type": "string",
                        "enum": [
                            "active",
                            "paused"
                        ]
                    },
                    "paused_reason": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "enum": [
                            "owner",
                            "auto",
                            "gone",
                            null
                        ],
                        "description": "owner = paused by you; auto = kept failing; gone = the receiver answered 410."
                    },
                    "paused_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 with the business's UTC offset."
                    },
                    "failure_streak": {
                        "type": "integer",
                        "description": "Failed attempts in a row."
                    },
                    "last_delivered_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 with the business's UTC offset."
                    },
                    "last_failed_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 with the business's UTC offset."
                    },
                    "secret_hint": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "The last 4 of the signing secret (\"whsec_…1a2b\"). The secret itself is only in the 201 of POST v1/webhooks (and in the app)."
                    },
                    "created_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 with the business's UTC offset."
                    },
                    "updated_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 with the business's UTC offset."
                    }
                },
                "required": [
                    "id",
                    "label",
                    "url",
                    "events",
                    "status",
                    "paused_reason",
                    "paused_at",
                    "failure_streak",
                    "last_delivered_at",
                    "last_failed_at",
                    "secret_hint",
                    "created_at",
                    "updated_at"
                ]
            },
            "WebhookCreated": {
                "allOf": [
                    {
                        "$ref": "#/components/schemas/Webhook"
                    },
                    {
                        "type": "object",
                        "properties": {
                            "secret": {
                                "type": [
                                    "string",
                                    "null"
                                ],
                                "description": "The signing secret (whsec_…), shown ONCE. null when this answer is an Idempotency-Key replay."
                            }
                        },
                        "required": [
                            "secret"
                        ]
                    }
                ]
            },
            "WebhookCreate": {
                "type": "object",
                "properties": {
                    "url": {
                        "type": "string",
                        "description": "https on a public host (no private, loopback, link-local or reserved address; checked again at every send).",
                        "maxLength": 600,
                        "format": "uri"
                    },
                    "events": {
                        "oneOf": [
                            {
                                "type": "array",
                                "items": {
                                    "type": "string",
                                    "enum": [
                                        "lead.created",
                                        "lead.status_changed",
                                        "lead.sold",
                                        "appointment.created",
                                        "quote.approved",
                                        "invoice.paid",
                                        "booking.requested",
                                        "booking.rescheduled",
                                        "booking.canceled",
                                        "website.form",
                                        "campaign.lead",
                                        "chat.lead",
                                        "card.lead",
                                        "review.received",
                                        "lighting.reply",
                                        "lighting.postcard_opened"
                                    ]
                                },
                                "minItems": 1
                            },
                            {
                                "type": "string",
                                "description": "Comma-separated."
                            }
                        ]
                    },
                    "label": {
                        "type": "string",
                        "description": "Defaults to the URL's host.",
                        "maxLength": 80
                    },
                    "paused": {
                        "type": "boolean",
                        "default": false
                    }
                },
                "required": [
                    "url",
                    "events"
                ]
            },
            "WebhookPatch": {
                "type": "object",
                "properties": {
                    "url": {
                        "type": "string",
                        "maxLength": 600,
                        "format": "uri"
                    },
                    "events": {
                        "oneOf": [
                            {
                                "type": "array",
                                "items": {
                                    "type": "string",
                                    "enum": [
                                        "lead.created",
                                        "lead.status_changed",
                                        "lead.sold",
                                        "appointment.created",
                                        "quote.approved",
                                        "invoice.paid",
                                        "booking.requested",
                                        "booking.rescheduled",
                                        "booking.canceled",
                                        "website.form",
                                        "campaign.lead",
                                        "chat.lead",
                                        "card.lead",
                                        "review.received",
                                        "lighting.reply",
                                        "lighting.postcard_opened"
                                    ]
                                },
                                "minItems": 1
                            },
                            {
                                "type": "string"
                            }
                        ]
                    },
                    "label": {
                        "type": "string",
                        "maxLength": 80
                    },
                    "paused": {
                        "type": "boolean",
                        "description": "true pauses (queued deliveries are held); false resumes (held deliveries younger than 3 days are sent)."
                    }
                },
                "description": "Send at least one field. Only what is sent changes."
            },
            "WebhookTestResult": {
                "type": "object",
                "properties": {
                    "webhook_id": {
                        "type": "integer"
                    },
                    "event": {
                        "type": "string"
                    },
                    "delivered": {
                        "type": "boolean",
                        "description": "The receiver answered 2xx."
                    },
                    "status_code": {
                        "type": [
                            "integer",
                            "null"
                        ]
                    },
                    "error": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "response_snippet": {
                        "type": "string",
                        "description": "The receiver's answer, cleaned, ≤300 characters."
                    }
                },
                "required": [
                    "webhook_id",
                    "event",
                    "delivered",
                    "status_code",
                    "error",
                    "response_snippet"
                ]
            },
            "Delivery": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string",
                        "description": "dlv_…: the X-FieldStacker-Delivery header (unchanged across retries)."
                    },
                    "event": {
                        "type": "string"
                    },
                    "event_id": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "evt_…: the body's id."
                    },
                    "test": {
                        "type": "boolean"
                    },
                    "webhook_id": {
                        "type": [
                            "integer",
                            "null"
                        ],
                        "description": "null for a note row that was never sent."
                    },
                    "webhook_label": {
                        "type": "string",
                        "description": "The label when it was queued."
                    },
                    "status": {
                        "type": "string",
                        "enum": [
                            "delivered",
                            "failed",
                            "retrying",
                            "queued",
                            "sending",
                            "held",
                            "skipped"
                        ]
                    },
                    "attempts": {
                        "type": "integer"
                    },
                    "max_attempts": {
                        "type": "integer"
                    },
                    "will_retry": {
                        "type": "boolean"
                    },
                    "next_attempt_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 with the business's UTC offset."
                    },
                    "last_status_code": {
                        "type": [
                            "integer",
                            "null"
                        ]
                    },
                    "last_error": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "response_snippet": {
                        "type": "string"
                    },
                    "duration_ms": {
                        "type": [
                            "integer",
                            "null"
                        ]
                    },
                    "created_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 with the business's UTC offset."
                    },
                    "updated_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 with the business's UTC offset."
                    },
                    "completed_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 with the business's UTC offset."
                    }
                },
                "required": [
                    "id",
                    "event",
                    "event_id",
                    "test",
                    "webhook_id",
                    "webhook_label",
                    "status",
                    "attempts",
                    "max_attempts",
                    "will_retry",
                    "next_attempt_at",
                    "last_status_code",
                    "last_error",
                    "response_snippet",
                    "duration_ms",
                    "created_at",
                    "updated_at",
                    "completed_at"
                ],
                "description": "One event to one webhook. Never the body, the request headers or the secret."
            },
            "EventType": {
                "type": "object",
                "properties": {
                    "key": {
                        "type": "string",
                        "enum": [
                            "lead.created",
                            "lead.status_changed",
                            "lead.sold",
                            "appointment.created",
                            "quote.approved",
                            "invoice.paid",
                            "booking.requested",
                            "booking.rescheduled",
                            "booking.canceled",
                            "website.form",
                            "campaign.lead",
                            "chat.lead",
                            "card.lead",
                            "review.received",
                            "lighting.reply",
                            "lighting.postcard_opened"
                        ]
                    },
                    "name": {
                        "type": "string"
                    },
                    "description": {
                        "type": "string"
                    }
                },
                "required": [
                    "key",
                    "name",
                    "description"
                ]
            },
            "EventDetail": {
                "allOf": [
                    {
                        "$ref": "#/components/schemas/EventType"
                    },
                    {
                        "type": "object",
                        "properties": {
                            "headers": {
                                "type": "array",
                                "items": {
                                    "type": "string"
                                }
                            },
                            "sample": {
                                "type": "object",
                                "additionalProperties": true,
                                "description": "A sample body (\"test\": true): the envelope (id, event, test, api_version, occurred_at, occurred_at_local, timezone, company_id, company_name) + the event's flat fields."
                            }
                        },
                        "required": [
                            "headers",
                            "sample"
                        ]
                    }
                ]
            },
            "Usage": {
                "type": "object",
                "properties": {
                    "key": {
                        "type": "object",
                        "properties": {
                            "prefix": {
                                "type": "string",
                                "description": "The first 10 characters (\"fsk_1a2b3c\")."
                            },
                            "created_at": {
                                "type": [
                                    "string",
                                    "null"
                                ],
                                "format": "date-time",
                                "description": "ISO 8601 with the business's UTC offset."
                            },
                            "last_used_at": {
                                "type": [
                                    "string",
                                    "null"
                                ],
                                "format": "date-time",
                                "description": "ISO 8601 with the business's UTC offset."
                            }
                        },
                        "required": [
                            "prefix",
                            "created_at",
                            "last_used_at"
                        ]
                    },
                    "rate_limit": {
                        "type": "object",
                        "properties": {
                            "limit": {
                                "type": "integer",
                                "description": "Requests per key per window."
                            },
                            "window_seconds": {
                                "type": "integer"
                            },
                            "used": {
                                "type": "integer",
                                "description": "In the current window, this call included."
                            },
                            "remaining": {
                                "type": "integer"
                            },
                            "resets_at": {
                                "type": [
                                    "string",
                                    "null"
                                ],
                                "format": "date-time",
                                "description": "When the oldest call in the window ages out. ISO 8601 with the business's UTC offset."
                            }
                        },
                        "required": [
                            "limit",
                            "window_seconds",
                            "used",
                            "remaining",
                            "resets_at"
                        ]
                    },
                    "requests": {
                        "type": "object",
                        "properties": {
                            "last_hour": {
                                "type": "integer"
                            },
                            "today": {
                                "type": "integer",
                                "description": "Since local midnight."
                            },
                            "last_24_hours": {
                                "type": "integer"
                            },
                            "last_30_days": {
                                "type": "integer"
                            },
                            "errors_last_24_hours": {
                                "type": "integer",
                                "description": "Status 400 and up."
                            },
                            "rate_limited_last_24_hours": {
                                "type": "integer",
                                "description": "Status 429."
                            }
                        },
                        "required": [
                            "last_hour",
                            "today",
                            "last_24_hours",
                            "last_30_days",
                            "errors_last_24_hours",
                            "rate_limited_last_24_hours"
                        ],
                        "description": "Every count includes this call."
                    },
                    "by_day": {
                        "type": "array",
                        "description": "Newest first, local dates, days with calls only (this call not included).",
                        "items": {
                            "type": "object",
                            "properties": {
                                "date": {
                                    "type": "string",
                                    "format": "date"
                                },
                                "requests": {
                                    "type": "integer"
                                },
                                "errors": {
                                    "type": "integer"
                                },
                                "rate_limited": {
                                    "type": "integer"
                                }
                            },
                            "required": [
                                "date",
                                "requests",
                                "errors",
                                "rate_limited"
                            ]
                        }
                    },
                    "retention_days": {
                        "type": "integer"
                    },
                    "timezone": {
                        "type": "string"
                    }
                },
                "required": [
                    "key",
                    "rate_limit",
                    "requests",
                    "by_day",
                    "retention_days",
                    "timezone"
                ]
            },
            "Product": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "integer"
                    },
                    "key": {
                        "type": "string",
                        "description": "The price-list key."
                    },
                    "name": {
                        "type": "string"
                    },
                    "sku": {
                        "type": "string",
                        "description": "The model / part number."
                    },
                    "category": {
                        "type": "string"
                    },
                    "price": {
                        "type": "string",
                        "pattern": "^-?\\d+\\.\\d{2}$",
                        "examples": [
                            "1250.00"
                        ],
                        "description": "The customer price."
                    },
                    "currency": {
                        "type": "string",
                        "examples": [
                            "USD"
                        ]
                    },
                    "unit": {
                        "type": "string",
                        "enum": [
                            "each"
                        ],
                        "description": "Always each: every line is quantity × price."
                    },
                    "taxable": {
                        "const": true,
                        "description": "Always true: an estimate or invoice charges its tax rate on every line."
                    },
                    "active": {
                        "type": "boolean",
                        "description": "false = a hidden item."
                    },
                    "shown_on_website": {
                        "type": "boolean"
                    }
                },
                "required": [
                    "id",
                    "key",
                    "name",
                    "sku",
                    "category",
                    "price",
                    "currency",
                    "unit",
                    "taxable",
                    "active",
                    "shown_on_website"
                ],
                "description": "A price-list item (Equipment & pricing). Read-only. Cost, labor cost, pass-through cost and the image path are never returned."
            },
            "InventoryItem": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string",
                        "description": "inv_<id> install inventory (adjustable), sub_<id> sub-dealer stock (read-only).",
                        "pattern": "^(inv|sub)_[1-9]\\d*$"
                    },
                    "source": {
                        "type": "string",
                        "enum": [
                            "install_inventory",
                            "sub_dealer_stock"
                        ]
                    },
                    "name": {
                        "type": "string"
                    },
                    "sku": {
                        "type": "string"
                    },
                    "key": {
                        "type": "string"
                    },
                    "product_id": {
                        "type": [
                            "integer",
                            "null"
                        ],
                        "description": "The price-list item with the same key, or null."
                    },
                    "held_by": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string",
                                "description": "rep_<id> (GET v1/team: the number after rep_).",
                                "pattern": "^rep_[1-9]\\d*$"
                            },
                            "name": {
                                "type": "string"
                            }
                        },
                        "required": [
                            "id",
                            "name"
                        ]
                    },
                    "quantity_on_hand": {
                        "type": "integer"
                    },
                    "low_stock_at": {
                        "type": [
                            "integer",
                            "null"
                        ],
                        "description": "The low-stock level, null when none is set."
                    },
                    "is_low": {
                        "type": "boolean",
                        "description": "A level is set and quantity_on_hand ≤ it (the app's own rule)."
                    },
                    "unit_price": {
                        "type": "string",
                        "pattern": "^-?\\d+\\.\\d{2}$",
                        "examples": [
                            "1250.00"
                        ]
                    },
                    "currency": {
                        "type": "string"
                    },
                    "adjustable": {
                        "type": "boolean",
                        "description": "true = POST v1/inventory/{id}/adjust works (install inventory only)."
                    },
                    "updated_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 with the business's UTC offset."
                    }
                },
                "required": [
                    "id",
                    "source",
                    "name",
                    "sku",
                    "key",
                    "product_id",
                    "held_by",
                    "quantity_on_hand",
                    "low_stock_at",
                    "is_low",
                    "unit_price",
                    "currency",
                    "adjustable",
                    "updated_at"
                ],
                "description": "Stock on hand per person (a tech's van, a rep's own gear). Unit cost, stock value and the photo are never returned."
            },
            "InventoryMovement": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string",
                        "pattern": "^mv_[1-9]\\d*$"
                    },
                    "item_id": {
                        "type": "string",
                        "pattern": "^inv_[1-9]\\d*$"
                    },
                    "item_name": {
                        "type": "string"
                    },
                    "sku": {
                        "type": "string"
                    },
                    "held_by": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string",
                                "description": "rep_<id> (GET v1/team: the number after rep_).",
                                "pattern": "^rep_[1-9]\\d*$"
                            },
                            "name": {
                                "type": "string"
                            }
                        },
                        "required": [
                            "id",
                            "name"
                        ]
                    },
                    "quantity_change": {
                        "type": "integer",
                        "description": "+ received, − used."
                    },
                    "reason": {
                        "type": "string",
                        "enum": [
                            "receive",
                            "use",
                            "install",
                            "adjust",
                            "transfer",
                            "side_job"
                        ]
                    },
                    "note": {
                        "type": "string"
                    },
                    "quote_id": {
                        "type": [
                            "integer",
                            "null"
                        ],
                        "description": "Set when the stock went to a job on one of your own quotes."
                    },
                    "customer_id": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "cus_q<quote id> when quote_id is set."
                    },
                    "created_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 with the business's UTC offset."
                    }
                },
                "required": [
                    "id",
                    "item_id",
                    "item_name",
                    "sku",
                    "held_by",
                    "quantity_change",
                    "reason",
                    "note",
                    "quote_id",
                    "customer_id",
                    "created_at"
                ],
                "description": "One line of the install inventory's stock in / out log."
            },
            "InventoryAdjust": {
                "type": "object",
                "properties": {
                    "quantity_change": {
                        "type": "integer",
                        "description": "A non-zero whole number: + received, − used. Never goes below 0.",
                        "minimum": -100000,
                        "maximum": 100000
                    },
                    "set_quantity": {
                        "type": "integer",
                        "description": "The count on hand; the API records the difference.",
                        "minimum": 0,
                        "maximum": 1000000
                    },
                    "reason": {
                        "type": "string",
                        "enum": [
                            "receive",
                            "use",
                            "adjust"
                        ],
                        "description": "Default: receive when up, use when down."
                    },
                    "note": {
                        "type": "string",
                        "description": "Default \"Received (API)\" / \"Used (API)\".",
                        "maxLength": 200
                    }
                },
                "description": "Send exactly one of quantity_change or set_quantity. Any other field is 422 unknown_field.",
                "additionalProperties": false
            },
            "InventoryAdjustAnswer": {
                "type": "object",
                "properties": {
                    "ok": {
                        "const": true
                    },
                    "data": {
                        "$ref": "#/components/schemas/InventoryItem"
                    },
                    "movement": {
                        "oneOf": [
                            {
                                "$ref": "#/components/schemas/InventoryMovement"
                            },
                            {
                                "type": "null"
                            }
                        ],
                        "description": "The logged movement; null when nothing changed (the count was already right, or a decrease was clamped at 0)."
                    }
                },
                "required": [
                    "ok",
                    "data",
                    "movement"
                ]
            },
            "DocLineIn": {
                "type": "object",
                "properties": {
                    "type": {
                        "type": "string",
                        "enum": [
                            "item",
                            "discount"
                        ],
                        "default": "item"
                    },
                    "product_id": {
                        "type": "integer",
                        "description": "A price-list item: its name and list price unless you send your own (its list cost goes on the line for job costing, never returned).",
                        "minimum": 1
                    },
                    "name": {
                        "type": "string",
                        "description": "Required on a line of your own. Default \"Discount\" on a discount.",
                        "maxLength": 160
                    },
                    "quantity": {
                        "type": [
                            "string",
                            "number"
                        ],
                        "description": "More than 0, default 1. A JSON number or a decimal string, at most 2 decimal places.",
                        "pattern": "^\\d{1,8}(\\.\\d{1,2})?$"
                    },
                    "unit_price": {
                        "type": [
                            "string",
                            "number"
                        ],
                        "description": "Required on a line of your own. A JSON number or a decimal string, at most 2 decimal places.",
                        "pattern": "^\\d{1,8}(\\.\\d{1,2})?$"
                    },
                    "amount": {
                        "type": [
                            "string",
                            "number"
                        ],
                        "description": "Discount lines only: the dollars off the document (more than 0). A JSON number or a decimal string, at most 2 decimal places.",
                        "pattern": "^\\d{1,8}(\\.\\d{1,2})?$"
                    }
                },
                "description": "One of: {product_id, quantity?, unit_price?, name?} · {name, quantity?, unit_price} · {type: \"discount\", amount, name?}. customer_hidden, hidden, commission, unit_cost, cost, procure, inventory_item_id, sub_dealer_item_id are refused (422 not_allowed); any other field is 422 unknown_field.",
                "additionalProperties": false
            },
            "DocCreate": {
                "type": "object",
                "properties": {
                    "customer_id": {
                        "type": "string",
                        "description": "An existing customer (cus_…): its name, phone, email and address are filled in."
                    },
                    "customer": {
                        "type": "object",
                        "properties": {
                            "name": {
                                "type": "string",
                                "maxLength": 160
                            },
                            "phone": {
                                "type": "string",
                                "maxLength": 40
                            },
                            "email": {
                                "type": "string",
                                "maxLength": 160,
                                "format": "email"
                            },
                            "address": {
                                "type": "string",
                                "maxLength": 300
                            },
                            "contact_name": {
                                "type": "string",
                                "maxLength": 120
                            }
                        },
                        "description": "Fields sent here win over the customer_id ones.",
                        "additionalProperties": false
                    },
                    "lines": {
                        "type": "array",
                        "maxItems": 100,
                        "items": {
                            "$ref": "#/components/schemas/DocLineIn"
                        },
                        "description": "Discounts are added after the other lines. Your automatic line rules add their lines too, as in the app."
                    }
                },
                "description": "customer_id and / or customer (at least a name, email or phone). notes, tax_rate, labor, status, dates, number and every payment field are 422 field_not_writable.",
                "additionalProperties": false
            },
            "DocPatch": {
                "type": "object",
                "properties": {
                    "lines": {
                        "type": "array",
                        "maxItems": 100,
                        "items": {
                            "$ref": "#/components/schemas/DocLineIn"
                        },
                        "description": "The WHOLE new list of the customer's lines (hidden lines are never touched)."
                    }
                },
                "required": [
                    "lines"
                ],
                "description": "Only a draft can be changed (else 409 not_draft). Any other field is 422 field_not_writable / unknown_field.",
                "additionalProperties": false
            },
            "DocLineWithId": {
                "allOf": [
                    {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": [
                                    "integer",
                                    "null"
                                ],
                                "description": "The line's id."
                            }
                        },
                        "required": [
                            "id"
                        ]
                    },
                    {
                        "$ref": "#/components/schemas/DocLine"
                    }
                ]
            },
            "EstimateWritten": {
                "allOf": [
                    {
                        "type": "object",
                        "properties": {
                            "lines": {
                                "type": "array",
                                "items": {
                                    "$ref": "#/components/schemas/DocLineWithId"
                                }
                            }
                        },
                        "description": "The write answers add each line's id."
                    },
                    {
                        "$ref": "#/components/schemas/Estimate"
                    }
                ],
                "description": "The same shape as GET v1/estimates/{id}, each line with its id."
            },
            "InvoiceWritten": {
                "allOf": [
                    {
                        "type": "object",
                        "properties": {
                            "lines": {
                                "type": "array",
                                "items": {
                                    "$ref": "#/components/schemas/DocLineWithId"
                                }
                            }
                        },
                        "description": "The write answers add each line's id."
                    },
                    {
                        "$ref": "#/components/schemas/Invoice"
                    }
                ],
                "description": "The same shape as GET v1/invoices/{id}, each line with its id."
            },
            "DocSent": {
                "type": "object",
                "properties": {
                    "to": {
                        "type": "string",
                        "description": "The customer email it went to."
                    },
                    "delivered": {
                        "type": "boolean",
                        "description": "false only on a server with no email transport (a test install)."
                    }
                },
                "required": [
                    "to",
                    "delivered"
                ]
            },
            "Payment": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string",
                        "description": "pay_s<invoice> · dep_s<invoice> · dep_c<change order> · pay_q<quote> (card) · pay_k<quote> (recorded by hand) · pay_v<recurring visit>.",
                        "pattern": "^(pay_s|dep_s|dep_c|pay_q|pay_k|pay_v)[1-9]\\d*$"
                    },
                    "type": {
                        "type": "string",
                        "enum": [
                            "payment",
                            "deposit"
                        ]
                    },
                    "amount": {
                        "type": "string",
                        "pattern": "^-?\\d+\\.\\d{2}$",
                        "examples": [
                            "1250.00"
                        ],
                        "description": "An invoice payment is the bill less every deposit listed, so its payments add up to amount_paid."
                    },
                    "currency": {
                        "type": "string"
                    },
                    "method": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "enum": [
                            "cash",
                            "check",
                            "card",
                            "card_other",
                            "zelle",
                            "venmo",
                            "cashapp",
                            "paypal",
                            "split",
                            "other",
                            null
                        ],
                        "description": "null on an old row with none recorded."
                    },
                    "method_label": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "card_brand": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Only when FieldStacker stored it."
                    },
                    "card_last4": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Only when FieldStacker stored it.",
                        "pattern": "^\\d{4}$"
                    },
                    "status": {
                        "type": "string",
                        "enum": [
                            "succeeded",
                            "refunded",
                            "disputed"
                        ]
                    },
                    "paid_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 with the business's UTC offset."
                    },
                    "invoice_id": {
                        "type": [
                            "integer",
                            "null"
                        ]
                    },
                    "estimate_id": {
                        "type": [
                            "integer",
                            "null"
                        ]
                    },
                    "change_order": {
                        "type": [
                            "integer",
                            "null"
                        ],
                        "description": "The change order's number (its deposit)."
                    },
                    "quote_id": {
                        "type": [
                            "integer",
                            "null"
                        ]
                    },
                    "customer_id": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "source": {
                        "type": "string",
                        "enum": [
                            "invoice",
                            "invoice_deposit",
                            "change_order_deposit",
                            "quote",
                            "recurring_plan"
                        ]
                    }
                },
                "required": [
                    "id",
                    "type",
                    "amount",
                    "currency",
                    "method",
                    "method_label",
                    "card_brand",
                    "card_last4",
                    "status",
                    "paid_at",
                    "invoice_id",
                    "estimate_id",
                    "change_order",
                    "quote_id",
                    "customer_id",
                    "source"
                ],
                "description": "Money received. Read-only: the API never charges, refunds or records a payment. Fees, processor ids and receipt URLs are never returned."
            },
            "Quote": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "integer"
                    },
                    "type": {
                        "type": "string",
                        "enum": [
                            "install",
                            "fiber",
                            "cleaning",
                            "service"
                        ]
                    },
                    "status": {
                        "type": "string",
                        "enum": [
                            "quoted",
                            "viewed",
                            "expired",
                            "approved",
                            "install_pending",
                            "installed",
                            "declined"
                        ]
                    },
                    "customer": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": [
                                    "string",
                                    "null"
                                ],
                                "description": "cus_q<id>, null when the quote has no contact."
                            },
                            "name": {
                                "type": "string"
                            },
                            "phone": {
                                "type": "string"
                            },
                            "email": {
                                "type": "string"
                            },
                            "address": {
                                "type": "string"
                            }
                        },
                        "required": [
                            "id",
                            "name",
                            "phone",
                            "email",
                            "address"
                        ]
                    },
                    "plan": {
                        "type": "object",
                        "properties": {
                            "name": {
                                "type": "string"
                            },
                            "term_months": {
                                "type": [
                                    "integer",
                                    "null"
                                ]
                            },
                            "monthly": {
                                "type": [
                                    "string",
                                    "null"
                                ],
                                "pattern": "^-?\\d+\\.\\d{2}$"
                            },
                            "upfront": {
                                "type": [
                                    "string",
                                    "null"
                                ],
                                "pattern": "^-?\\d+\\.\\d{2}$"
                            },
                            "total_value": {
                                "type": [
                                    "string",
                                    "null"
                                ],
                                "pattern": "^-?\\d+\\.\\d{2}$"
                            }
                        },
                        "required": [
                            "name",
                            "term_months",
                            "monthly",
                            "upfront",
                            "total_value"
                        ]
                    },
                    "price": {
                        "type": [
                            "object",
                            "null"
                        ],
                        "description": "The quote's money in its own terms; null when nothing was priced.",
                        "properties": {
                            "amount": {
                                "type": "string",
                                "pattern": "^-?\\d+\\.\\d{2}$",
                                "examples": [
                                    "1250.00"
                                ]
                            },
                            "per": {
                                "type": [
                                    "string",
                                    "null"
                                ],
                                "enum": [
                                    "month",
                                    "visit",
                                    null
                                ]
                            },
                            "cadence": {
                                "type": [
                                    "string",
                                    "null"
                                ]
                            }
                        },
                        "required": [
                            "amount",
                            "per",
                            "cadence"
                        ]
                    },
                    "frequency": {
                        "type": "string",
                        "description": "one_time, or a recurring clean's frequency."
                    },
                    "currency": {
                        "type": "string"
                    },
                    "lines": {
                        "type": "array",
                        "maxItems": 60,
                        "description": "The customer-facing breakdown the quote showed.",
                        "items": {
                            "type": "object",
                            "properties": {
                                "name": {
                                    "type": "string"
                                },
                                "detail": {
                                    "type": "string"
                                },
                                "price": {
                                    "type": "string",
                                    "pattern": "^-?\\d+\\.\\d{2}$",
                                    "examples": [
                                        "1250.00"
                                    ]
                                },
                                "included": {
                                    "type": "boolean"
                                },
                                "monthly": {
                                    "type": "string",
                                    "pattern": "^-?\\d+\\.\\d{2}$",
                                    "examples": [
                                        "1250.00"
                                    ],
                                    "description": "Present on a monthly line."
                                }
                            },
                            "required": [
                                "name",
                                "detail",
                                "price",
                                "included"
                            ]
                        }
                    },
                    "equipment": {
                        "type": "array",
                        "maxItems": 60,
                        "items": {
                            "type": "object",
                            "properties": {
                                "key": {
                                    "type": "string"
                                },
                                "name": {
                                    "type": "string"
                                },
                                "quantity": {
                                    "type": "integer",
                                    "minimum": 1,
                                    "maximum": 999
                                }
                            },
                            "required": [
                                "key",
                                "name",
                                "quantity"
                            ]
                        }
                    },
                    "invoice_id": {
                        "type": [
                            "integer",
                            "null"
                        ],
                        "description": "The invoice the quote is billed through."
                    },
                    "created_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 with the business's UTC offset."
                    },
                    "viewed_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 with the business's UTC offset."
                    },
                    "expires_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 with the business's UTC offset."
                    },
                    "approved_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 with the business's UTC offset."
                    },
                    "installed_on": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date"
                    },
                    "install_verified": {
                        "type": "boolean"
                    },
                    "declined_on": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date"
                    }
                },
                "required": [
                    "id",
                    "type",
                    "status",
                    "customer",
                    "plan",
                    "price",
                    "frequency",
                    "currency",
                    "lines",
                    "equipment",
                    "invoice_id",
                    "created_at",
                    "viewed_at",
                    "expires_at",
                    "approved_at",
                    "installed_on",
                    "install_verified",
                    "declined_on"
                ],
                "description": "A quote-builder quote (read-only, customer-safe). Never: commission, holdback, chargebacks, costs, fees, the quote link / token, card or processor ids, GPS, consent IPs."
            },
            "TeamMember": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "integer",
                        "description": "Use it as tech_id in jobs and the schedule."
                    },
                    "name": {
                        "type": "string"
                    },
                    "role": {
                        "type": "string",
                        "enum": [
                            "owner",
                            "sales",
                            "tech",
                            "sales_tech"
                        ]
                    },
                    "role_label": {
                        "type": "string"
                    },
                    "works_jobs": {
                        "type": "boolean"
                    },
                    "relationship": {
                        "type": "string",
                        "enum": [
                            "owner",
                            "team_member",
                            "seat",
                            "crew"
                        ]
                    },
                    "assignable": {
                        "type": "boolean",
                        "description": "A job can be handed to them (POST v1/jobs, assign)."
                    },
                    "email": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Only for the business's own staff; null for a tech in a dealer's shared pool."
                    },
                    "active": {
                        "type": "boolean"
                    },
                    "created_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 with the business's UTC offset."
                    }
                },
                "required": [
                    "id",
                    "name",
                    "role",
                    "role_label",
                    "works_jobs",
                    "relationship",
                    "assignable",
                    "email",
                    "active",
                    "created_at"
                ],
                "description": "One of the business's people. Never: pay rates, commission plans, passwords, tokens, phone numbers."
            },
            "Job": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string",
                        "description": "ap_<id>: the same id GET v1/bookings uses.",
                        "pattern": "^ap_[1-9]\\d*$"
                    },
                    "type": {
                        "type": "string",
                        "enum": [
                            "install",
                            "service_booking",
                            "service_call",
                            "plan_visit",
                            "job"
                        ]
                    },
                    "status": {
                        "type": "string",
                        "enum": [
                            "unscheduled",
                            "scheduled",
                            "unconfirmed",
                            "confirmed",
                            "en_route",
                            "in_progress",
                            "completed",
                            "canceled",
                            "needs_reschedule"
                        ],
                        "description": "The Schedule board's own status."
                    },
                    "title": {
                        "type": "string"
                    },
                    "start_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 with the business's UTC offset."
                    },
                    "end_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 with the business's UTC offset."
                    },
                    "duration_min": {
                        "type": [
                            "integer",
                            "null"
                        ]
                    },
                    "arrival_window_min": {
                        "type": [
                            "integer",
                            "null"
                        ]
                    },
                    "timezone": {
                        "type": "string"
                    },
                    "customer": {
                        "type": "object",
                        "properties": {
                            "name": {
                                "type": "string"
                            },
                            "phone": {
                                "type": "string"
                            },
                            "email": {
                                "type": "string"
                            },
                            "address": {
                                "type": "string"
                            }
                        },
                        "required": [
                            "name",
                            "phone",
                            "email",
                            "address"
                        ]
                    },
                    "assigned_to": {
                        "oneOf": [
                            {
                                "type": "object",
                                "properties": {
                                    "id": {
                                        "type": "integer"
                                    },
                                    "name": {
                                        "type": "string"
                                    }
                                },
                                "required": [
                                    "id",
                                    "name"
                                ]
                            },
                            {
                                "type": "null"
                            }
                        ],
                        "description": "Who does it."
                    },
                    "offer_status": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "enum": [
                            "pending",
                            "accepted",
                            "declined",
                            null
                        ],
                        "description": "The tech's answer to the offer."
                    },
                    "booked_by": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "integer"
                            },
                            "name": {
                                "type": "string"
                            }
                        },
                        "required": [
                            "id",
                            "name"
                        ]
                    },
                    "job_number": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "notes": {
                        "type": "string"
                    },
                    "invoice_id": {
                        "type": [
                            "integer",
                            "null"
                        ],
                        "description": "GET v1/invoices/{id}."
                    },
                    "estimate_id": {
                        "type": [
                            "integer",
                            "null"
                        ],
                        "description": "GET v1/estimates/{id}."
                    },
                    "quote_id": {
                        "type": [
                            "integer",
                            "null"
                        ]
                    },
                    "plan_id": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "sp_<id> or cp_<id> on a plan visit.",
                        "pattern": "^(sp|cp)_[1-9]\\d*$"
                    },
                    "currency": {
                        "type": "string"
                    },
                    "lines": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/DocLine"
                        },
                        "description": "The linked invoice's (or estimate's) customer lines. Never a hidden line."
                    },
                    "equipment": {
                        "type": "array",
                        "description": "What goes in: names and quantities only.",
                        "items": {
                            "type": "object",
                            "properties": {
                                "name": {
                                    "type": "string"
                                },
                                "quantity": {
                                    "type": "string",
                                    "description": "Decimal string without trailing zeros (\"2\", \"2.5\")."
                                }
                            },
                            "required": [
                                "name",
                                "quantity"
                            ]
                        }
                    },
                    "en_route_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 with the business's UTC offset."
                    },
                    "checked_in_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 with the business's UTC offset."
                    },
                    "completed_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 with the business's UTC offset."
                    },
                    "canceled_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 with the business's UTC offset."
                    },
                    "created_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 with the business's UTC offset."
                    },
                    "updated_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "The last change (a move, an offer answered, on the way, check-in, finish, cancel). ISO 8601 with the business's UTC offset."
                    }
                },
                "required": [
                    "id",
                    "type",
                    "status",
                    "title",
                    "start_at",
                    "end_at",
                    "duration_min",
                    "arrival_window_min",
                    "timezone",
                    "customer",
                    "assigned_to",
                    "offer_status",
                    "booked_by",
                    "job_number",
                    "notes",
                    "invoice_id",
                    "estimate_id",
                    "quote_id",
                    "plan_id",
                    "currency",
                    "lines",
                    "equipment",
                    "en_route_at",
                    "checked_in_at",
                    "completed_at",
                    "canceled_at",
                    "created_at",
                    "updated_at"
                ],
                "description": "Work on the schedule that a tech does. Never: tech pay, bonuses, mileage, fees, tips, costs, tokens, calendar ids, signature or photo paths, check-in GPS."
            },
            "JobCreate": {
                "type": "object",
                "properties": {
                    "tech_id": {
                        "type": "integer",
                        "description": "A person with assignable: true."
                    },
                    "start_at": {
                        "type": "string",
                        "description": "Date AND time, in the future (read in the tech's own zone).",
                        "format": "date-time"
                    },
                    "arrival_window": {
                        "type": "boolean",
                        "default": false,
                        "description": "true = a 2-hour arrival window from start_at."
                    },
                    "customer": {
                        "type": "object",
                        "properties": {
                            "name": {
                                "type": "string",
                                "maxLength": 200
                            },
                            "phone": {
                                "type": "string",
                                "maxLength": 40
                            },
                            "email": {
                                "type": "string",
                                "maxLength": 160,
                                "format": "email"
                            },
                            "address": {
                                "type": "string",
                                "maxLength": 500
                            },
                            "lat": {
                                "type": "number",
                                "minimum": -90,
                                "maximum": 90
                            },
                            "lng": {
                                "type": "number",
                                "minimum": -180,
                                "maximum": 180
                            }
                        },
                        "required": [
                            "name"
                        ],
                        "description": "May also be sent flat."
                    },
                    "items": {
                        "type": "array",
                        "minItems": 1,
                        "maxItems": 50,
                        "items": {
                            "type": "object",
                            "properties": {
                                "name": {
                                    "type": "string",
                                    "maxLength": 160
                                },
                                "quantity": {
                                    "type": "integer",
                                    "description": "Default 1.",
                                    "minimum": 1,
                                    "maximum": 999
                                },
                                "key": {
                                    "type": "string",
                                    "description": "Your catalog key.",
                                    "maxLength": 60
                                }
                            },
                            "required": [
                                "name"
                            ]
                        }
                    },
                    "job_number": {
                        "type": "string",
                        "maxLength": 60
                    },
                    "force": {
                        "type": "boolean",
                        "default": false,
                        "description": "true = dispatch even if the tech is short of tracked equipment."
                    }
                },
                "required": [
                    "tech_id",
                    "start_at",
                    "items"
                ],
                "description": "A bonus field is refused (422 not_supported): tech pay is set in FieldStacker."
            },
            "JobPatch": {
                "type": "object",
                "properties": {
                    "start_at": {
                        "type": "string",
                        "description": "Date and time, in the future.",
                        "format": "date-time"
                    },
                    "arrival_window": {
                        "type": "boolean",
                        "description": "A sold install only."
                    }
                },
                "required": [
                    "start_at"
                ]
            },
            "JobAssign": {
                "type": "object",
                "properties": {
                    "tech_id": {
                        "type": "integer",
                        "description": "A tech the job's seller can hand work to."
                    }
                },
                "required": [
                    "tech_id"
                ]
            },
            "ServicePlan": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string",
                        "description": "sp_<id> a service plan, cp_<id> a recurring clean.",
                        "pattern": "^(sp|cp)_[1-9]\\d*$"
                    },
                    "type": {
                        "type": "string",
                        "enum": [
                            "service_plan",
                            "cleaning_plan"
                        ]
                    },
                    "status": {
                        "type": "string",
                        "description": "active, paused, canceled or ended; a recurring clean can also be past_due."
                    },
                    "customer": {
                        "type": "object",
                        "properties": {
                            "name": {
                                "type": "string"
                            },
                            "contact_name": {
                                "type": "string"
                            },
                            "phone": {
                                "type": "string"
                            },
                            "email": {
                                "type": "string"
                            },
                            "address": {
                                "type": "string"
                            }
                        },
                        "required": [
                            "name",
                            "contact_name",
                            "phone",
                            "email",
                            "address"
                        ]
                    },
                    "schedule": {
                        "type": "object",
                        "properties": {
                            "frequency": {
                                "type": "string",
                                "description": "w1–w4, m1, m2, m3, m6, m12 (service plan) or a clean's frequency (weekly, biweekly, monthly, …)."
                            },
                            "frequency_label": {
                                "type": "string"
                            },
                            "label": {
                                "type": "string"
                            },
                            "interval_days": {
                                "type": "integer",
                                "description": "Recurring cleans only."
                            },
                            "first_visit_on": {
                                "type": [
                                    "string",
                                    "null"
                                ],
                                "format": "date"
                            },
                            "visit_time": {
                                "type": [
                                    "string",
                                    "null"
                                ],
                                "description": "HH:MM."
                            },
                            "duration_min": {
                                "type": [
                                    "integer",
                                    "null"
                                ]
                            },
                            "ends": {
                                "type": "object",
                                "properties": {
                                    "mode": {
                                        "type": "string",
                                        "description": "never, after or on."
                                    },
                                    "after_visits": {
                                        "type": [
                                            "integer",
                                            "null"
                                        ]
                                    },
                                    "on": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "format": "date"
                                    },
                                    "label": {
                                        "type": "string"
                                    }
                                },
                                "required": [
                                    "mode",
                                    "after_visits",
                                    "on",
                                    "label"
                                ]
                            }
                        },
                        "required": [
                            "frequency",
                            "frequency_label",
                            "label",
                            "first_visit_on",
                            "visit_time",
                            "duration_min",
                            "ends"
                        ]
                    },
                    "tech": {
                        "oneOf": [
                            {
                                "type": "object",
                                "properties": {
                                    "id": {
                                        "type": "integer"
                                    },
                                    "name": {
                                        "type": "string"
                                    }
                                },
                                "required": [
                                    "id",
                                    "name"
                                ]
                            },
                            {
                                "type": "null"
                            }
                        ]
                    },
                    "currency": {
                        "type": "string"
                    },
                    "price_per_visit": {
                        "type": "string",
                        "pattern": "^-?\\d+\\.\\d{2}$",
                        "examples": [
                            "1250.00"
                        ],
                        "description": "Tax included."
                    },
                    "tax_rate": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Percent; null on a recurring clean."
                    },
                    "lines": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/DocLine"
                        },
                        "description": "Empty on a recurring clean."
                    },
                    "autopay": {
                        "type": "boolean",
                        "description": "Autopay on and a card saved. Never card details."
                    },
                    "next_visit_on": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date"
                    },
                    "visits_made": {
                        "type": "integer"
                    },
                    "notes": {
                        "type": "string"
                    },
                    "source_invoice_id": {
                        "type": [
                            "integer",
                            "null"
                        ]
                    },
                    "created_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 with the business's UTC offset."
                    },
                    "updated_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 with the business's UTC offset."
                    }
                },
                "required": [
                    "id",
                    "type",
                    "status",
                    "customer",
                    "schedule",
                    "tech",
                    "currency",
                    "price_per_visit",
                    "tax_rate",
                    "lines",
                    "autopay",
                    "next_visit_on",
                    "visits_made",
                    "notes",
                    "source_invoice_id",
                    "created_at",
                    "updated_at"
                ],
                "description": "A recurring plan (read-only). Card brand, last 4, Stripe ids and card / portal links are never returned."
            },
            "ServicePlanVisit": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string",
                        "pattern": "^(spv|cpv)_[1-9]\\d*$"
                    },
                    "date": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date"
                    },
                    "status": {
                        "type": "string"
                    },
                    "job_id": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "ap_<id>: GET v1/jobs/{id}."
                    },
                    "invoice_id": {
                        "type": [
                            "integer",
                            "null"
                        ]
                    },
                    "completed": {
                        "type": "boolean"
                    },
                    "paid": {
                        "type": "boolean"
                    },
                    "amount": {
                        "type": "string",
                        "pattern": "^-?\\d+\\.\\d{2}$",
                        "examples": [
                            "1250.00"
                        ],
                        "description": "Recurring-clean visits only."
                    }
                },
                "required": [
                    "id",
                    "date",
                    "status",
                    "job_id",
                    "invoice_id",
                    "completed",
                    "paid"
                ]
            },
            "ServicePlanDetail": {
                "allOf": [
                    {
                        "$ref": "#/components/schemas/ServicePlan"
                    },
                    {
                        "type": "object",
                        "properties": {
                            "visits": {
                                "type": "array",
                                "maxItems": 100,
                                "items": {
                                    "$ref": "#/components/schemas/ServicePlanVisit"
                                },
                                "description": "The latest 100, newest first."
                            }
                        },
                        "required": [
                            "visits"
                        ]
                    }
                ]
            },
            "MonitoringAccount": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string",
                        "pattern": "^ma_[1-9]\\d*$"
                    },
                    "status": {
                        "type": "string",
                        "description": "active, paused, canceled or ended."
                    },
                    "customer": {
                        "type": "object",
                        "properties": {
                            "name": {
                                "type": "string"
                            },
                            "phone": {
                                "type": "string"
                            },
                            "email": {
                                "type": "string"
                            },
                            "address": {
                                "type": "string"
                            }
                        },
                        "required": [
                            "name",
                            "phone",
                            "email",
                            "address"
                        ]
                    },
                    "currency": {
                        "type": "string"
                    },
                    "monthly_amount": {
                        "type": "string",
                        "pattern": "^-?\\d+\\.\\d{2}$",
                        "examples": [
                            "1250.00"
                        ],
                        "description": "Per month, tax included (quarterly / yearly spread over the months)."
                    },
                    "monthly_rmr": {
                        "type": "string",
                        "pattern": "^-?\\d+\\.\\d{2}$",
                        "examples": [
                            "1250.00"
                        ],
                        "description": "The same before tax."
                    },
                    "billing": {
                        "type": "object",
                        "properties": {
                            "frequency": {
                                "type": "string"
                            },
                            "frequency_label": {
                                "type": "string"
                            },
                            "amount_per_bill": {
                                "type": "string",
                                "pattern": "^-?\\d+\\.\\d{2}$",
                                "examples": [
                                    "1250.00"
                                ]
                            },
                            "next_bill_on": {
                                "type": [
                                    "string",
                                    "null"
                                ],
                                "format": "date"
                            },
                            "tax_rate": {
                                "type": "string"
                            }
                        },
                        "required": [
                            "frequency",
                            "frequency_label",
                            "amount_per_bill",
                            "next_bill_on",
                            "tax_rate"
                        ]
                    },
                    "lines": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/DocLine"
                        }
                    },
                    "contract": {
                        "type": "object",
                        "properties": {
                            "start_on": {
                                "type": [
                                    "string",
                                    "null"
                                ],
                                "format": "date"
                            },
                            "term_months": {
                                "type": "integer"
                            },
                            "term_end_on": {
                                "type": [
                                    "string",
                                    "null"
                                ],
                                "format": "date"
                            },
                            "auto_renew": {
                                "type": "boolean"
                            },
                            "month_to_month": {
                                "type": "boolean"
                            }
                        },
                        "required": [
                            "start_on",
                            "term_months",
                            "term_end_on",
                            "auto_renew",
                            "month_to_month"
                        ]
                    },
                    "central_station": {
                        "type": "object",
                        "properties": {
                            "name": {
                                "type": [
                                    "string",
                                    "null"
                                ]
                            },
                            "account_number": {
                                "type": [
                                    "string",
                                    "null"
                                ]
                            }
                        },
                        "required": [
                            "name",
                            "account_number"
                        ]
                    },
                    "alarmcom_customer_id": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "panel": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "contract_number": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "autopay": {
                        "type": "boolean"
                    },
                    "past_due": {
                        "type": "boolean",
                        "description": "An unpaid bill older than today."
                    },
                    "past_due_amount": {
                        "type": "string",
                        "pattern": "^-?\\d+\\.\\d{2}$",
                        "examples": [
                            "1250.00"
                        ]
                    },
                    "days_past_due": {
                        "type": "integer",
                        "description": "From the oldest unpaid bill."
                    },
                    "unpaid_invoices": {
                        "type": "integer"
                    },
                    "created_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 with the business's UTC offset."
                    },
                    "updated_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 with the business's UTC offset."
                    }
                },
                "required": [
                    "id",
                    "status",
                    "customer",
                    "currency",
                    "monthly_amount",
                    "monthly_rmr",
                    "billing",
                    "lines",
                    "contract",
                    "central_station",
                    "alarmcom_customer_id",
                    "panel",
                    "contract_number",
                    "autopay",
                    "past_due",
                    "past_due_amount",
                    "days_past_due",
                    "unpaid_invoices",
                    "created_at",
                    "updated_at"
                ],
                "description": "An alarm monitoring billing account (read-only). Zones, the emergency call list, the passcode flag and card details are never returned."
            },
            "ScheduleEntry": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string",
                        "description": "ap_<id>, bk_<id> or cpv_<id>: the record's own id.",
                        "pattern": "^(ap|bk|cpv)_[1-9]\\d*$"
                    },
                    "kind": {
                        "type": "string",
                        "enum": [
                            "job",
                            "appointment",
                            "online_booking",
                            "plan_visit"
                        ]
                    },
                    "job_type": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "enum": [
                            "install",
                            "service_booking",
                            "service_call",
                            "plan_visit",
                            "job",
                            null
                        ]
                    },
                    "status": {
                        "type": "string",
                        "description": "A job's board status, a booking's status, or awaiting_confirmation for a plan visit."
                    },
                    "title": {
                        "type": "string"
                    },
                    "start_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "null on an all-day plan visit. ISO 8601 with the business's UTC offset."
                    },
                    "end_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 with the business's UTC offset."
                    },
                    "date": {
                        "type": "string",
                        "description": "YYYY-MM-DD."
                    },
                    "all_day": {
                        "type": "boolean"
                    },
                    "timezone": {
                        "type": "string"
                    },
                    "person": {
                        "oneOf": [
                            {
                                "type": "object",
                                "properties": {
                                    "id": {
                                        "type": "integer"
                                    },
                                    "name": {
                                        "type": "string"
                                    }
                                },
                                "required": [
                                    "id",
                                    "name"
                                ]
                            },
                            {
                                "type": "null"
                            }
                        ]
                    },
                    "customer": {
                        "type": "object",
                        "properties": {
                            "name": {
                                "type": "string"
                            },
                            "address": {
                                "type": "string"
                            }
                        },
                        "required": [
                            "name",
                            "address"
                        ]
                    },
                    "resource": {
                        "type": "string",
                        "description": "The full record: v1/jobs/…, v1/bookings/… or v1/service-plans/cp_…."
                    }
                },
                "required": [
                    "id",
                    "kind",
                    "job_type",
                    "status",
                    "title",
                    "start_at",
                    "end_at",
                    "date",
                    "all_day",
                    "timezone",
                    "person",
                    "customer",
                    "resource"
                ],
                "description": "One calendar entry. A view: it points at its record and never adds an id of its own."
            },
            "Contract": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "integer"
                    },
                    "title": {
                        "type": "string"
                    },
                    "status": {
                        "type": "string",
                        "enum": [
                            "draft",
                            "sent",
                            "viewed",
                            "signed",
                            "canceled"
                        ]
                    },
                    "template": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "integer"
                            },
                            "name": {
                                "type": "string"
                            },
                            "version": {
                                "type": "integer"
                            }
                        },
                        "required": [
                            "id",
                            "name",
                            "version"
                        ]
                    },
                    "customer": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": [
                                    "string",
                                    "null"
                                ],
                                "description": "cus_s… (from an estimate / invoice) or cus_q… (from a quote), else null."
                            },
                            "name": {
                                "type": "string"
                            },
                            "email": {
                                "type": "string"
                            },
                            "phone": {
                                "type": "string"
                            },
                            "address": {
                                "type": "string"
                            }
                        },
                        "required": [
                            "id",
                            "name",
                            "email",
                            "phone",
                            "address"
                        ]
                    },
                    "source": {
                        "type": "object",
                        "properties": {
                            "type": {
                                "type": [
                                    "string",
                                    "null"
                                ],
                                "description": "estimate, invoice, quote, monitoring_account, customer or blank."
                            },
                            "id": {
                                "type": [
                                    "integer",
                                    "null"
                                ]
                            }
                        },
                        "required": [
                            "type",
                            "id"
                        ]
                    },
                    "rep_id": {
                        "type": "integer"
                    },
                    "door_to_door": {
                        "type": "boolean"
                    },
                    "cancel_by": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date",
                        "description": "The cancel-by date of a door-to-door sale."
                    },
                    "countersign_required": {
                        "type": "boolean"
                    },
                    "countersigned_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 with the business's UTC offset."
                    },
                    "view_count": {
                        "type": "integer"
                    },
                    "document_id": {
                        "type": [
                            "integer",
                            "null"
                        ],
                        "description": "Its Documents entry once signed."
                    },
                    "signed_pdf_url": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Signed contracts only: the lasting link the signer and you were emailed. Anyone with it can open the signed copy."
                    },
                    "created_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 with the business's UTC offset."
                    },
                    "updated_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 with the business's UTC offset."
                    },
                    "sent_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 with the business's UTC offset."
                    },
                    "first_viewed_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 with the business's UTC offset."
                    },
                    "signed_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 with the business's UTC offset."
                    },
                    "canceled_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 with the business's UTC offset."
                    },
                    "canceled_by": {
                        "type": [
                            "string",
                            "null"
                        ]
                    }
                },
                "required": [
                    "id",
                    "title",
                    "status",
                    "template",
                    "customer",
                    "source",
                    "rep_id",
                    "door_to_door",
                    "cancel_by",
                    "countersign_required",
                    "countersigned_at",
                    "view_count",
                    "document_id",
                    "signed_pdf_url",
                    "created_at",
                    "updated_at",
                    "sent_at",
                    "first_viewed_at",
                    "signed_at",
                    "canceled_at",
                    "canceled_by"
                ],
                "description": "An e-sign contract. Never: its words, filled-in values, signature images, the signer's IP / device, the file path, the signing token."
            },
            "ContractTemplate": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "integer",
                        "description": "template_id for POST v1/contracts."
                    },
                    "name": {
                        "type": "string"
                    },
                    "version": {
                        "type": "integer"
                    },
                    "door_to_door": {
                        "type": "boolean"
                    },
                    "cancel_days": {
                        "type": "integer"
                    },
                    "countersign_required": {
                        "type": "boolean"
                    },
                    "fields": {
                        "type": "array",
                        "items": {
                            "type": "object",
                            "properties": {
                                "key": {
                                    "type": "string"
                                },
                                "kind": {
                                    "type": "string"
                                },
                                "label": {
                                    "type": "string"
                                }
                            },
                            "required": [
                                "key",
                                "kind",
                                "label"
                            ]
                        }
                    },
                    "created_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 with the business's UTC offset."
                    },
                    "updated_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 with the business's UTC offset."
                    }
                },
                "required": [
                    "id",
                    "name",
                    "version",
                    "door_to_door",
                    "cancel_days",
                    "countersign_required",
                    "fields",
                    "created_at",
                    "updated_at"
                ],
                "description": "A current template (its latest version)."
            },
            "ContractCreate": {
                "type": "object",
                "properties": {
                    "template_id": {
                        "type": "integer",
                        "description": "A current template (GET v1/contract-templates)."
                    },
                    "estimate_id": {
                        "type": "integer"
                    },
                    "invoice_id": {
                        "type": "integer"
                    },
                    "quote_id": {
                        "type": "integer",
                        "description": "An alarm quote."
                    },
                    "monitoring_account_id": {
                        "type": "integer",
                        "description": "The number of an ma_<id>."
                    },
                    "customer_id": {
                        "type": "string",
                        "description": "cus_…: fills from that customer's records."
                    },
                    "customer": {
                        "type": "object",
                        "properties": {
                            "name": {
                                "type": "string",
                                "maxLength": 120
                            },
                            "phone": {
                                "type": "string",
                                "maxLength": 40
                            },
                            "email": {
                                "type": "string",
                                "maxLength": 160,
                                "format": "email"
                            },
                            "address": {
                                "type": "string",
                                "maxLength": 300
                            }
                        },
                        "description": "Someone not in FieldStacker yet: at least a name, phone or email."
                    }
                },
                "required": [
                    "template_id"
                ],
                "description": "template_id plus EXACTLY ONE of estimate_id, invoice_id, quote_id, monitoring_account_id, customer_id, customer. Makes a draft; nothing is sent."
            },
            "ContractSend": {
                "type": "object",
                "properties": {
                    "channel": {
                        "type": "string",
                        "enum": [
                            "email",
                            "link"
                        ],
                        "default": "email",
                        "description": "email = ✉️ Email the link (the customer gets \"Please review and sign\" from your business). link = 🔗 Copy link (nothing is sent; you get sign_url)."
                    }
                }
            },
            "ContractSentAnswer": {
                "type": "object",
                "properties": {
                    "ok": {
                        "const": true
                    },
                    "sent": {
                        "type": "object",
                        "properties": {
                            "channel": {
                                "type": "string",
                                "enum": [
                                    "email",
                                    "link"
                                ]
                            },
                            "to": {
                                "type": "string",
                                "description": "email channel."
                            },
                            "delivered": {
                                "type": "boolean",
                                "description": "email channel. false only on a server with no email transport."
                            },
                            "sign_url": {
                                "type": "string",
                                "description": "link channel: the customer's signing link. Anyone with it can sign as the customer."
                            }
                        },
                        "required": [
                            "channel"
                        ]
                    },
                    "data": {
                        "$ref": "#/components/schemas/Contract"
                    }
                },
                "required": [
                    "ok",
                    "sent",
                    "data"
                ]
            },
            "Document": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "integer"
                    },
                    "kind": {
                        "type": "string",
                        "description": "contract."
                    },
                    "status": {
                        "type": "string",
                        "description": "signed or canceled."
                    },
                    "title": {
                        "type": "string"
                    },
                    "template_name": {
                        "type": "string"
                    },
                    "customer": {
                        "type": "object",
                        "properties": {
                            "name": {
                                "type": "string"
                            },
                            "email": {
                                "type": "string"
                            },
                            "phone": {
                                "type": "string"
                            },
                            "address": {
                                "type": "string"
                            }
                        },
                        "required": [
                            "name",
                            "email",
                            "phone",
                            "address"
                        ]
                    },
                    "source": {
                        "type": "object",
                        "properties": {
                            "type": {
                                "type": [
                                    "string",
                                    "null"
                                ],
                                "description": "estimate_or_invoice, quote, monitoring_account, customer or blank."
                            },
                            "id": {
                                "type": [
                                    "integer",
                                    "null"
                                ]
                            }
                        },
                        "required": [
                            "type",
                            "id"
                        ]
                    },
                    "contract_id": {
                        "type": [
                            "integer",
                            "null"
                        ]
                    },
                    "rep_id": {
                        "type": "integer"
                    },
                    "doc_hash": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "SHA-256 of the signed words."
                    },
                    "download_url": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "The Documents page's own download: opens only for someone signed in to FieldStacker who may see it."
                    },
                    "signed_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 with the business's UTC offset."
                    },
                    "created_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 with the business's UTC offset."
                    },
                    "updated_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 with the business's UTC offset."
                    }
                },
                "required": [
                    "id",
                    "kind",
                    "status",
                    "title",
                    "template_name",
                    "customer",
                    "source",
                    "contract_id",
                    "rep_id",
                    "doc_hash",
                    "download_url",
                    "signed_at",
                    "created_at",
                    "updated_at"
                ],
                "description": "A Documents page record (every signed contract is filed there). The file path and search text are never returned."
            },
            "Note": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string",
                        "description": "ln_<id> a lead's History entry, cn_<id> a customer's note.",
                        "pattern": "^(ln|cn)_[1-9]\\d*$"
                    },
                    "type": {
                        "type": "string",
                        "enum": [
                            "note",
                            "voice_note"
                        ]
                    },
                    "text": {
                        "type": "string"
                    },
                    "rep_id": {
                        "type": [
                            "integer",
                            "null"
                        ]
                    },
                    "created_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 with the business's UTC offset."
                    }
                },
                "required": [
                    "id",
                    "type",
                    "text",
                    "rep_id",
                    "created_at"
                ]
            },
            "NotesAnswer": {
                "allOf": [
                    {
                        "type": "object",
                        "required": [
                            "ok",
                            "data",
                            "next_cursor",
                            "limit"
                        ],
                        "properties": {
                            "ok": {
                                "const": true
                            },
                            "data": {
                                "type": "array",
                                "items": {
                                    "$ref": "#/components/schemas/Note"
                                }
                            },
                            "next_cursor": {
                                "type": [
                                    "string",
                                    "null"
                                ],
                                "description": "Pass as `cursor` (with the same filters) for the next page; null on the last page."
                            },
                            "limit": {
                                "type": "integer"
                            }
                        }
                    },
                    {
                        "type": "object",
                        "properties": {
                            "subject": {
                                "type": "object",
                                "properties": {
                                    "type": {
                                        "type": "string",
                                        "enum": [
                                            "lead",
                                            "customer"
                                        ]
                                    },
                                    "id": {
                                        "type": [
                                            "integer",
                                            "string"
                                        ],
                                        "description": "The lead id, or the customer's cus_… id."
                                    },
                                    "notes": {
                                        "type": "string",
                                        "description": "The note as it stands now."
                                    },
                                    "updated_at": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "format": "date-time",
                                        "description": "ISO 8601 with the business's UTC offset."
                                    }
                                },
                                "required": [
                                    "type",
                                    "id",
                                    "notes",
                                    "updated_at"
                                ]
                            }
                        },
                        "required": [
                            "subject"
                        ]
                    }
                ],
                "description": "Lead: its History note entries (+ kept voice-note transcripts), newest first, paged. Customer: the one ✏️ note."
            },
            "NoteCreate": {
                "type": "object",
                "properties": {
                    "lead_id": {
                        "type": "integer"
                    },
                    "customer_id": {
                        "type": "string",
                        "description": "cus_…."
                    },
                    "text": {
                        "type": "string",
                        "description": "The line to add.",
                        "maxLength": 500
                    }
                },
                "required": [
                    "text"
                ],
                "description": "lead_id or customer_id (not both). Adds a line; a note that would pass 500 (lead) / 4000 (customer) characters is 422 note_full, never cut."
            },
            "Photo": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string",
                        "description": "med_<id> Photos hub, pin_<id> a pin's house photo, job_<id> an estimate / invoice photo.",
                        "pattern": "^(med|pin|job)_[1-9]\\d*$"
                    },
                    "source": {
                        "type": "string",
                        "enum": [
                            "media",
                            "pin",
                            "job"
                        ]
                    },
                    "kind": {
                        "type": "string",
                        "enum": [
                            "photo",
                            "video",
                            "audio"
                        ]
                    },
                    "mime": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "caption": {
                        "type": "string"
                    },
                    "tag": {
                        "type": "string",
                        "description": "A pin photo's tag, or before / after on a job photo."
                    },
                    "lead_id": {
                        "type": [
                            "integer",
                            "null"
                        ]
                    },
                    "job_id": {
                        "type": [
                            "integer",
                            "null"
                        ],
                        "description": "The estimate / invoice id."
                    },
                    "customer_name": {
                        "type": "string"
                    },
                    "address": {
                        "type": "string"
                    },
                    "rep_id": {
                        "type": [
                            "integer",
                            "null"
                        ]
                    },
                    "width": {
                        "type": [
                            "integer",
                            "null"
                        ]
                    },
                    "height": {
                        "type": [
                            "integer",
                            "null"
                        ]
                    },
                    "view_url": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "The app's own sign-in-gated route; there is no public photo link and the API serves no files."
                    },
                    "captured_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 with the business's UTC offset."
                    },
                    "created_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 with the business's UTC offset."
                    }
                },
                "required": [
                    "id",
                    "source",
                    "kind",
                    "mime",
                    "caption",
                    "tag",
                    "lead_id",
                    "job_id",
                    "customer_name",
                    "address",
                    "rep_id",
                    "width",
                    "height",
                    "view_url",
                    "captured_at",
                    "created_at"
                ],
                "description": "Photo metadata (read-only). File paths are never returned."
            },
            "Review": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "integer"
                    },
                    "source": {
                        "type": "string",
                        "enum": [
                            "card"
                        ]
                    },
                    "rating": {
                        "type": "integer",
                        "minimum": 1,
                        "maximum": 5
                    },
                    "reviewer_name": {
                        "type": "string"
                    },
                    "text": {
                        "type": "string"
                    },
                    "hidden": {
                        "type": "boolean",
                        "description": "Hidden from the card in the app."
                    },
                    "rep_id": {
                        "type": "integer"
                    },
                    "created_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 with the business's UTC offset."
                    }
                },
                "required": [
                    "id",
                    "source",
                    "rating",
                    "reviewer_name",
                    "text",
                    "hidden",
                    "rep_id",
                    "created_at"
                ],
                "description": "A star review on a digital card. The reviewer's IP is never returned."
            },
            "Knock": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "integer",
                        "description": "The pin id (also works with GET v1/leads/{id})."
                    },
                    "lead_id": {
                        "type": "integer"
                    },
                    "address": {
                        "type": "string"
                    },
                    "lat": {
                        "type": [
                            "number",
                            "null"
                        ]
                    },
                    "lng": {
                        "type": [
                            "number",
                            "null"
                        ]
                    },
                    "status": {
                        "type": "string",
                        "description": "Your disposition key."
                    },
                    "status_label": {
                        "type": "string",
                        "description": "Your label for it."
                    },
                    "rep_id": {
                        "type": "integer",
                        "description": "Who knocked it (else the assignee, else the pin's owner)."
                    },
                    "is_business": {
                        "type": "boolean"
                    },
                    "verified": {
                        "type": "boolean",
                        "description": "The rep's phone was at the door."
                    },
                    "first_knocked_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 with the business's UTC offset."
                    },
                    "last_knocked_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 with the business's UTC offset."
                    },
                    "won_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 with the business's UTC offset."
                    },
                    "appointment_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 with the business's UTC offset."
                    },
                    "created_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 with the business's UTC offset."
                    },
                    "updated_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 with the business's UTC offset."
                    }
                },
                "required": [
                    "id",
                    "lead_id",
                    "address",
                    "lat",
                    "lng",
                    "status",
                    "status_label",
                    "rep_id",
                    "is_business",
                    "verified",
                    "first_knocked_at",
                    "last_knocked_at",
                    "won_at",
                    "appointment_at",
                    "created_at",
                    "updated_at"
                ],
                "description": "A worked door (read-only). Contact details stay on GET v1/leads/{id}."
            },
            "KnockDetail": {
                "allOf": [
                    {
                        "$ref": "#/components/schemas/Knock"
                    },
                    {
                        "type": "object",
                        "properties": {
                            "visits": {
                                "type": "array",
                                "maxItems": 100,
                                "description": "The pin's disposition changes, newest first.",
                                "items": {
                                    "type": "object",
                                    "properties": {
                                        "change": {
                                            "type": "string",
                                            "description": "e.g. \"Not home → Callback\"."
                                        },
                                        "rep_id": {
                                            "type": [
                                                "integer",
                                                "null"
                                            ]
                                        },
                                        "at_the_door": {
                                            "type": [
                                                "boolean",
                                                "null"
                                            ]
                                        },
                                        "at": {
                                            "type": [
                                                "string",
                                                "null"
                                            ],
                                            "format": "date-time",
                                            "description": "ISO 8601 with the business's UTC offset."
                                        }
                                    },
                                    "required": [
                                        "change",
                                        "rep_id",
                                        "at_the_door",
                                        "at"
                                    ]
                                }
                            }
                        },
                        "required": [
                            "visits"
                        ]
                    }
                ]
            },
            "Campaign": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "integer"
                    },
                    "name": {
                        "type": "string"
                    },
                    "type": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "status": {
                        "type": "string",
                        "description": "active, paused, draft or archived."
                    },
                    "service": {
                        "type": "string"
                    },
                    "source_label": {
                        "type": "string"
                    },
                    "goal": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "rep_id": {
                        "type": "integer"
                    },
                    "landing_url": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "The public page printed on its flyers and postcards."
                    },
                    "stats": {
                        "type": "object",
                        "properties": {
                            "sends": {
                                "type": "integer",
                                "description": "Postcards mailed (test sends left out)."
                            },
                            "opens": {
                                "type": "integer",
                                "description": "Mailed households who scanned."
                            },
                            "scans": {
                                "type": "integer",
                                "description": "Every scan."
                            },
                            "visits": {
                                "type": "integer",
                                "description": "Landing-page visits."
                            },
                            "replies": {
                                "type": "integer",
                                "description": "Leads it brought in."
                            },
                            "bookings": {
                                "type": "integer",
                                "description": "Those leads with a booked visit."
                            }
                        },
                        "required": [
                            "sends",
                            "opens",
                            "scans",
                            "visits",
                            "replies",
                            "bookings"
                        ]
                    },
                    "created_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 with the business's UTC offset."
                    },
                    "updated_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 with the business's UTC offset."
                    },
                    "archived_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 with the business's UTC offset."
                    }
                },
                "required": [
                    "id",
                    "name",
                    "type",
                    "status",
                    "service",
                    "source_label",
                    "goal",
                    "rep_id",
                    "landing_url",
                    "stats",
                    "created_at",
                    "updated_at",
                    "archived_at"
                ],
                "description": "A marketing campaign (read-only). Budgets, ad spend, postage and page settings are never returned."
            },
            "CampaignSummary": {
                "type": "object",
                "properties": {
                    "from": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 with the business's UTC offset."
                    },
                    "to": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 with the business's UTC offset."
                    },
                    "campaigns": {
                        "type": "object",
                        "properties": {
                            "count": {
                                "type": "integer"
                            },
                            "visits": {
                                "type": "integer"
                            },
                            "replies": {
                                "type": "integer"
                            }
                        },
                        "required": [
                            "count",
                            "visits",
                            "replies"
                        ]
                    },
                    "direct_mail": {
                        "type": "object",
                        "properties": {
                            "mailings": {
                                "type": "integer"
                            },
                            "sends": {
                                "type": "integer"
                            },
                            "failed": {
                                "type": "integer"
                            },
                            "opens": {
                                "type": "integer"
                            },
                            "scans": {
                                "type": "integer"
                            }
                        },
                        "required": [
                            "mailings",
                            "sends",
                            "failed",
                            "opens",
                            "scans"
                        ],
                        "description": "Test sends and canceled mailings left out."
                    },
                    "lit_up_postcards": {
                        "type": "object",
                        "properties": {
                            "sends": {
                                "type": "integer"
                            },
                            "opens": {
                                "type": "integer"
                            },
                            "replies": {
                                "type": "integer"
                            }
                        },
                        "required": [
                            "sends",
                            "opens",
                            "replies"
                        ]
                    }
                },
                "required": [
                    "from",
                    "to",
                    "campaigns",
                    "direct_mail",
                    "lit_up_postcards"
                ]
            }
        },
        "parameters": {
            "limit": {
                "name": "limit",
                "in": "query",
                "required": false,
                "description": "1–100.",
                "schema": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 100,
                    "default": 50
                }
            },
            "cursor": {
                "name": "cursor",
                "in": "query",
                "required": false,
                "description": "next_cursor from the previous page (same route and filters).",
                "schema": {
                    "type": "string",
                    "maxLength": 400
                }
            },
            "idempotencyKey": {
                "name": "Idempotency-Key",
                "in": "header",
                "required": false,
                "description": "1–100 visible ASCII characters. A retry with the same key and body within 24 h gets the first answer (Idempotent-Replayed: true).",
                "schema": {
                    "type": "string",
                    "maxLength": 100
                }
            }
        },
        "responses": {
            "E400": {
                "description": "Bad parameter (bad_limit, bad_cursor, bad_status, …).",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        }
                    }
                }
            },
            "E401": {
                "description": "no_key / bad_key.",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        }
                    }
                }
            },
            "E403": {
                "description": "account_inactive, terms_not_accepted, plan_required or not_allowed.",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        }
                    }
                }
            },
            "E404": {
                "description": "not_found (anything outside your account is 404, never 403).",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        }
                    }
                }
            },
            "E405": {
                "description": "method_not_allowed.",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        }
                    }
                }
            },
            "E409": {
                "description": "Conflict (slot_unavailable, booking_disabled, not_changeable, webhook_limit, duplicate_url, idempotency_in_progress).",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        }
                    }
                }
            },
            "E422": {
                "description": "Validation (missing_contact, too_long, invalid, bad_email, bad_url, bad_events, nothing_to_change, idempotency_key_reused, …).",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        }
                    }
                }
            },
            "E429": {
                "description": "rate_limited (60/min per key; Retry-After: 60).",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        }
                    }
                }
            },
            "E500": {
                "description": "server_error / save_failed.",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        }
                    }
                }
            },
            "E503": {
                "description": "busy, idempotency_unavailable, too_many_records.",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        }
                    }
                }
            }
        }
    },
    "externalDocs": {
        "description": "Developer docs",
        "url": "https://www.fieldstacker.com/developers.php"
    }
}
