{
  "components": {
    "schemas": {
      "AccountOut": {
        "description": "Who you are authenticated as. Useful for checking a key works.",
        "example": {
          "account_name": "Kelvin's Kustom Kabinets",
          "actor": {
            "money_visible": true,
            "name": "Rob Owner",
            "role": "owner",
            "user_id": "e1d2c3b4-a596-4877-8695-a4b3c2d1e0f9"
          },
          "credential": "api_key",
          "environment": "live",
          "key_name": "Website contact form",
          "scopes": [
            "leads:write",
            "meta:read"
          ],
          "tenant_id": "5c8d2e1f-3a4b-4c6d-8e9f-0a1b2c3d4e5f"
        },
        "properties": {
          "account_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The account's name.",
            "title": "Account Name"
          },
          "actor": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ActorOut"
              },
              {
                "type": "null"
              }
            ],
            "description": "The user every call made with this credential acts as."
          },
          "credential": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "api_key, or oauth for a connected app (which can never manage the account or delete).",
            "title": "Credential"
          },
          "environment": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "live or sandbox.",
            "title": "Environment"
          },
          "key_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The label the account gave this key.",
            "title": "Key Name"
          },
          "scopes": {
            "description": "What this key is allowed to do.",
            "items": {
              "type": "string"
            },
            "title": "Scopes",
            "type": "array"
          },
          "tenant_id": {
            "description": "The account this key writes to.",
            "format": "uuid",
            "title": "Tenant Id",
            "type": "string"
          }
        },
        "required": [
          "tenant_id"
        ],
        "title": "AccountOut",
        "type": "object"
      },
      "ActorOut": {
        "description": "Who a credential acts as. Every write is theirs, with their current role.",
        "properties": {
          "money_visible": {
            "description": "Whether money fields are filled in for this user.",
            "title": "Money Visible",
            "type": "boolean"
          },
          "name": {
            "title": "Name",
            "type": "string"
          },
          "role": {
            "description": "production, office, manager, admin or owner.",
            "title": "Role",
            "type": "string"
          },
          "user_id": {
            "format": "uuid",
            "title": "User Id",
            "type": "string"
          }
        },
        "required": [
          "user_id",
          "name",
          "role",
          "money_visible"
        ],
        "title": "ActorOut",
        "type": "object"
      },
      "AddressIn": {
        "example": {
          "city": "Austin",
          "line1": "1200 Oak Street",
          "postal_code": "78701",
          "state": "TX"
        },
        "properties": {
          "city": {
            "anyOf": [
              {
                "maxLength": 255,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "City"
          },
          "line1": {
            "anyOf": [
              {
                "maxLength": 255,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Line1"
          },
          "line2": {
            "anyOf": [
              {
                "maxLength": 255,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Line2"
          },
          "postal_code": {
            "anyOf": [
              {
                "maxLength": 20,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "US ZIP or ZIP+4, or a Canadian postal code.",
            "title": "Postal Code"
          },
          "state": {
            "anyOf": [
              {
                "maxLength": 255,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "State"
          }
        },
        "title": "AddressIn",
        "type": "object"
      },
      "AddressOut": {
        "example": {
          "city": "Austin",
          "line1": "1200 Oak Street",
          "postal_code": "78701",
          "state": "TX"
        },
        "properties": {
          "city": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "City"
          },
          "line1": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Line1"
          },
          "line2": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Line2"
          },
          "postal_code": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Postal Code"
          },
          "state": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "State, province or region.",
            "title": "State"
          }
        },
        "title": "AddressOut",
        "type": "object"
      },
      "ApiError": {
        "properties": {
          "code": {
            "description": "Stable code to branch on.",
            "enum": [
              "ERR_ACCOUNT_SUSPENDED",
              "ERR_ACTOR_INACTIVE",
              "ERR_AUTH_INVALID_KEY",
              "ERR_AUTH_KEY_REVOKED",
              "ERR_AUTH_MISSING_KEY",
              "ERR_CONFLICT",
              "ERR_DELETE_BLOCKED",
              "ERR_FEATURE_OFF",
              "ERR_FORBIDDEN",
              "ERR_IDEMPOTENCY_IN_PROGRESS",
              "ERR_IDEMPOTENCY_MISMATCH",
              "ERR_IDEMPOTENCY_REQUIRED",
              "ERR_INTERNAL",
              "ERR_LIMITER_UNAVAILABLE",
              "ERR_LOCKED",
              "ERR_NOT_ENTITLED",
              "ERR_NOT_FOUND",
              "ERR_NO_MAILBOX",
              "ERR_OAUTH_NOT_ALLOWED",
              "ERR_OVER_RECEIPT",
              "ERR_QUOTA_EXCEEDED",
              "ERR_RATE_LIMITED",
              "ERR_ROLE_REQUIRED",
              "ERR_SANDBOX_ONLY",
              "ERR_SCOPE_MISSING",
              "ERR_SEND_FAILED",
              "ERR_TENANT_HEADER",
              "ERR_TENANT_MISMATCH",
              "ERR_UPSTREAM",
              "ERR_UPSTREAM_TIMEOUT",
              "ERR_VALIDATION",
              "ERR_WRONG_ENVIRONMENT"
            ],
            "type": "string"
          },
          "detail": {
            "description": "A sentence a person can read.",
            "type": "string"
          },
          "errors": {
            "description": "Per-field problems on a validation error.",
            "items": {
              "properties": {
                "code": {
                  "type": "string"
                },
                "field": {
                  "type": "string"
                },
                "message": {
                  "type": "string"
                }
              },
              "type": "object"
            },
            "type": "array"
          },
          "request_id": {
            "description": "Quote this to support.",
            "type": "string"
          }
        },
        "required": [
          "detail",
          "code",
          "request_id"
        ],
        "title": "ApiError",
        "type": "object"
      },
      "AttemptOut": {
        "properties": {
          "attempt": {
            "title": "Attempt",
            "type": "integer"
          },
          "error": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Error"
          },
          "http_status": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Http Status"
          },
          "manual": {
            "default": false,
            "title": "Manual",
            "type": "boolean"
          },
          "response_excerpt": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The first 1,024 characters your receiver answered.",
            "title": "Response Excerpt"
          },
          "response_ms": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Response Ms"
          },
          "sent_at": {
            "format": "date-time",
            "title": "Sent At",
            "type": "string"
          },
          "status": {
            "title": "Status",
            "type": "string"
          }
        },
        "required": [
          "attempt",
          "status",
          "sent_at"
        ],
        "title": "AttemptOut",
        "type": "object"
      },
      "AttributeValueOut": {
        "properties": {
          "key": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Key"
          },
          "label": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Label"
          },
          "text": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The value as the app writes it, e.g. 3/4 or 49 x 97.",
            "title": "Text"
          }
        },
        "title": "AttributeValueOut",
        "type": "object"
      },
      "AuthorRef": {
        "description": "The person who wrote a note.",
        "example": {
          "id": "e1d2c3b4-a596-4877-8695-a4b3c2d1e0f9",
          "name": "Mia Lead"
        },
        "properties": {
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name"
          }
        },
        "required": [
          "id"
        ],
        "title": "AuthorRef",
        "type": "object"
      },
      "BomLineCreateIn": {
        "example": {
          "item_name": "3/4 white melamine, 49 x 97 sheet",
          "quantity": 12,
          "row_kind": "sheet",
          "stock_item_id": "5d6e7f80-91a2-4b3c-8d4e-5f60718293a4",
          "unit_cost": 42.5,
          "unit_name": "sheet",
          "work_order_id": "6e2b9a14-3c5d-4f70-8a91-b2c3d4e5f607"
        },
        "properties": {
          "category": {
            "anyOf": [
              {
                "maxLength": 100,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Category"
          },
          "depth": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Depth"
          },
          "description": {
            "anyOf": [
              {
                "maxLength": 2000,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description"
          },
          "height": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Height"
          },
          "item_name": {
            "maxLength": 255,
            "minLength": 1,
            "title": "Item Name",
            "type": "string"
          },
          "material_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "From GET /v1/materials.",
            "title": "Material Id"
          },
          "notes": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Notes"
          },
          "part_label": {
            "anyOf": [
              {
                "maxLength": 255,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Part Label"
          },
          "quantity": {
            "anyOf": [
              {
                "exclusiveMinimum": 0.0,
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Quantity"
          },
          "row_kind": {
            "anyOf": [
              {
                "enum": [
                  "part",
                  "sheet",
                  "hardware",
                  "edgeband"
                ],
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Row Kind"
          },
          "stock_item_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "What it is bought as. Sets material_id too.",
            "title": "Stock Item Id"
          },
          "thickness": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Thickness"
          },
          "unit_cost": {
            "anyOf": [
              {
                "minimum": 0.0,
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "description": "Per unit, in the account's currency.",
            "title": "Unit Cost"
          },
          "unit_name": {
            "anyOf": [
              {
                "maxLength": 50,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Unit Name"
          },
          "width": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Width"
          },
          "work_order_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "A work order on the same job.",
            "title": "Work Order Id"
          },
          "work_order_section_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "A step of that work order.",
            "title": "Work Order Section Id"
          }
        },
        "required": [
          "item_name"
        ],
        "title": "BomLineCreateIn",
        "type": "object"
      },
      "BomLineDeletedOut": {
        "example": {
          "deleted": true,
          "id": "7f8091a2-b3c4-4d5e-8f60-718293a4b5c6"
        },
        "properties": {
          "deleted": {
            "default": true,
            "title": "Deleted",
            "type": "boolean"
          },
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          }
        },
        "required": [
          "id"
        ],
        "title": "BomLineDeletedOut",
        "type": "object"
      },
      "BomLineOut": {
        "example": {
          "category": "Sheet goods",
          "created_at": "2026-10-02T11:00:00Z",
          "currency": "USD",
          "extended_cost": "510.00",
          "id": "7f8091a2-b3c4-4d5e-8f60-718293a4b5c6",
          "is_on_hand": false,
          "item_name": "3/4 white melamine, 49 x 97 sheet",
          "job_id": "3f9a1c77-5e3b-4a02-9d8e-2c7b6a1f0e4d",
          "material_id": "4c5d6e7f-8091-4a2b-9c3d-4e5f60718293",
          "ordered_qty": 12.0,
          "purchase_order": {
            "id": "8091a2b3-c4d5-4e6f-9071-8293a4b5c6d7",
            "reference": "PO112"
          },
          "quantity": 12.0,
          "received_qty": 0.0,
          "row_kind": "sheet",
          "sort_order": 0,
          "state": "ordered",
          "stock_item_id": "5d6e7f80-91a2-4b3c-8d4e-5f60718293a4",
          "to_order": 0.0,
          "unit_cost": "42.50",
          "unit_name": "sheet",
          "updated_at": "2026-10-03T09:30:00Z",
          "work_order_id": "6e2b9a14-3c5d-4f70-8a91-b2c3d4e5f607"
        },
        "properties": {
          "category": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Category"
          },
          "consumed_qty": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Consumed Qty"
          },
          "created_at": {
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "currency": {
            "default": "USD",
            "title": "Currency",
            "type": "string"
          },
          "depth": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Depth"
          },
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description"
          },
          "extended_cost": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Quantity times unit cost, two places.",
            "title": "Extended Cost"
          },
          "height": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Height"
          },
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "is_on_hand": {
            "default": false,
            "title": "Is On Hand",
            "type": "boolean"
          },
          "item_name": {
            "title": "Item Name",
            "type": "string"
          },
          "job_id": {
            "format": "uuid",
            "title": "Job Id",
            "type": "string"
          },
          "material_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Material Id"
          },
          "notes": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Notes"
          },
          "ordered_qty": {
            "default": 0.0,
            "title": "Ordered Qty",
            "type": "number"
          },
          "part_label": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Part Label"
          },
          "purchase_order": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/PurchaseOrderRef"
              },
              {
                "type": "null"
              }
            ]
          },
          "quantity": {
            "title": "Quantity",
            "type": "number"
          },
          "received_qty": {
            "default": 0.0,
            "title": "Received Qty",
            "type": "number"
          },
          "reserved_qty": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Reserved Qty"
          },
          "row_kind": {
            "default": "part",
            "description": "part, sheet, hardware or edgeband.",
            "title": "Row Kind",
            "type": "string"
          },
          "sort_order": {
            "default": 0,
            "title": "Sort Order",
            "type": "integer"
          },
          "state": {
            "default": "needed",
            "description": "Where it stands: needed, ordered, received, on_hand and so on.",
            "title": "State",
            "type": "string"
          },
          "stock_item_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Stock Item Id"
          },
          "thickness": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Thickness"
          },
          "to_order": {
            "default": 0.0,
            "title": "To Order",
            "type": "number"
          },
          "unit_cost": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Decimal string, up to four places. Null when the acting user cannot see costs.",
            "title": "Unit Cost"
          },
          "unit_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Unit Name"
          },
          "updated_at": {
            "format": "date-time",
            "title": "Updated At",
            "type": "string"
          },
          "width": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Width"
          },
          "work_order_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Work Order Id"
          },
          "work_order_section_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The step of the work order it is used at.",
            "title": "Work Order Section Id"
          }
        },
        "required": [
          "id",
          "job_id",
          "item_name",
          "quantity",
          "created_at",
          "updated_at"
        ],
        "title": "BomLineOut",
        "type": "object"
      },
      "BomLineUpdateIn": {
        "description": "Only the fields you send change. `work_order_id: null` takes the line\noff its work order.",
        "example": {
          "quantity": 14,
          "unit_cost": 41.75
        },
        "properties": {
          "category": {
            "anyOf": [
              {
                "maxLength": 100,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Category"
          },
          "depth": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Depth"
          },
          "description": {
            "anyOf": [
              {
                "maxLength": 2000,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description"
          },
          "height": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Height"
          },
          "item_name": {
            "anyOf": [
              {
                "maxLength": 255,
                "minLength": 1,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Item Name"
          },
          "material_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "From GET /v1/materials.",
            "title": "Material Id"
          },
          "notes": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Notes"
          },
          "part_label": {
            "anyOf": [
              {
                "maxLength": 255,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Part Label"
          },
          "quantity": {
            "anyOf": [
              {
                "exclusiveMinimum": 0.0,
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Quantity"
          },
          "row_kind": {
            "anyOf": [
              {
                "enum": [
                  "part",
                  "sheet",
                  "hardware",
                  "edgeband"
                ],
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Row Kind"
          },
          "stock_item_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "What it is bought as. Sets material_id too.",
            "title": "Stock Item Id"
          },
          "thickness": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Thickness"
          },
          "unit_cost": {
            "anyOf": [
              {
                "minimum": 0.0,
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "description": "Per unit, in the account's currency.",
            "title": "Unit Cost"
          },
          "unit_name": {
            "anyOf": [
              {
                "maxLength": 50,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Unit Name"
          },
          "width": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Width"
          },
          "work_order_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "A work order on the same job.",
            "title": "Work Order Id"
          },
          "work_order_section_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "A step of that work order.",
            "title": "Work Order Section Id"
          }
        },
        "title": "BomLineUpdateIn",
        "type": "object"
      },
      "BomOut": {
        "example": {
          "currency": "USD",
          "job_id": "3f9a1c77-5e3b-4a02-9d8e-2c7b6a1f0e4d",
          "lines": [
            {
              "category": "Sheet goods",
              "created_at": "2026-10-02T11:00:00Z",
              "currency": "USD",
              "extended_cost": "510.00",
              "id": "7f8091a2-b3c4-4d5e-8f60-718293a4b5c6",
              "is_on_hand": false,
              "item_name": "3/4 white melamine, 49 x 97 sheet",
              "job_id": "3f9a1c77-5e3b-4a02-9d8e-2c7b6a1f0e4d",
              "material_id": "4c5d6e7f-8091-4a2b-9c3d-4e5f60718293",
              "ordered_qty": 12.0,
              "purchase_order": {
                "id": "8091a2b3-c4d5-4e6f-9071-8293a4b5c6d7",
                "reference": "PO112"
              },
              "quantity": 12.0,
              "received_qty": 0.0,
              "row_kind": "sheet",
              "sort_order": 0,
              "state": "ordered",
              "stock_item_id": "5d6e7f80-91a2-4b3c-8d4e-5f60718293a4",
              "to_order": 0.0,
              "unit_cost": "42.50",
              "unit_name": "sheet",
              "updated_at": "2026-10-03T09:30:00Z",
              "work_order_id": "6e2b9a14-3c5d-4f70-8a91-b2c3d4e5f607"
            }
          ],
          "total_cost": "510.00"
        },
        "properties": {
          "currency": {
            "default": "USD",
            "title": "Currency",
            "type": "string"
          },
          "job_id": {
            "format": "uuid",
            "title": "Job Id",
            "type": "string"
          },
          "lines": {
            "items": {
              "$ref": "#/components/schemas/BomLineOut"
            },
            "title": "Lines",
            "type": "array"
          },
          "total_cost": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The sum of the lines' extended costs. Null when the acting user cannot see costs.",
            "title": "Total Cost"
          }
        },
        "required": [
          "job_id"
        ],
        "title": "BomOut",
        "type": "object"
      },
      "ContactIn": {
        "description": "The person who made the enquiry.",
        "example": {
          "email": "dana.whitfield@example.com",
          "first_name": "Dana",
          "last_name": "Whitfield",
          "phone_number": "(512) 555-0147"
        },
        "properties": {
          "email": {
            "anyOf": [
              {
                "maxLength": 255,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Email address. Optional, but a lead with neither an email nor a phone number cannot be followed up.",
            "title": "Email"
          },
          "first_name": {
            "anyOf": [
              {
                "maxLength": 50,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Given name, as the customer typed it.",
            "title": "First Name"
          },
          "last_name": {
            "anyOf": [
              {
                "maxLength": 50,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Family name, as the customer typed it.",
            "title": "Last Name"
          },
          "phone_number": {
            "anyOf": [
              {
                "maxLength": 15,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Phone number in whatever format the customer typed. It is stored as typed and also normalised for matching, so inbound texts and calls from this number find the lead automatically. Include the country code for numbers outside the account's own country.",
            "title": "Phone Number"
          }
        },
        "title": "ContactIn",
        "type": "object"
      },
      "ContactOut": {
        "example": {
          "created_at": "2026-09-10T14:22:05.412Z",
          "email": "dana.whitfield@example.com",
          "first_name": "Dana",
          "id": "b2d4e6f8-1a3c-5e7b-9d0f-2a4c6e8b0d1f",
          "jobs": [
            {
              "id": "3f9a1c77-5e3b-4a02-9d8e-2c7b6a1f0e4d",
              "name": "Whitfield kitchen remodel",
              "reference": "J1042"
            }
          ],
          "last_name": "Whitfield",
          "name": "Dana Whitfield",
          "phone_e164": "+15125550147",
          "phone_number": "5125550147",
          "updated_at": "2026-10-05T09:12:44.001Z"
        },
        "properties": {
          "created_at": {
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "email": {
            "default": "",
            "description": "Blank when the contact has no email.",
            "title": "Email",
            "type": "string"
          },
          "first_name": {
            "default": "",
            "title": "First Name",
            "type": "string"
          },
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "jobs": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/JobRef"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "The jobs this person is on. Present on a single contact.",
            "title": "Jobs"
          },
          "last_name": {
            "default": "",
            "title": "Last Name",
            "type": "string"
          },
          "name": {
            "default": "",
            "description": "First and last name together, or the email when there is no name.",
            "title": "Name",
            "type": "string"
          },
          "phone_e164": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The same number in international form, e.g. +15125550147. Null when it is not a usable number.",
            "title": "Phone E164"
          },
          "phone_number": {
            "default": "",
            "description": "As the office typed it. Blank when there is none.",
            "title": "Phone Number",
            "type": "string"
          },
          "updated_at": {
            "format": "date-time",
            "title": "Updated At",
            "type": "string"
          }
        },
        "required": [
          "id",
          "created_at",
          "updated_at"
        ],
        "title": "ContactOut",
        "type": "object"
      },
      "ContactPage": {
        "example": {
          "data": [
            {
              "created_at": "2026-09-10T14:22:05.412Z",
              "email": "dana.whitfield@example.com",
              "first_name": "Dana",
              "id": "b2d4e6f8-1a3c-5e7b-9d0f-2a4c6e8b0d1f",
              "last_name": "Whitfield",
              "name": "Dana Whitfield",
              "phone_e164": "+15125550147",
              "phone_number": "5125550147",
              "updated_at": "2026-10-05T09:12:44.001Z"
            }
          ],
          "has_more": true,
          "next_cursor": "eyJ2IjoiMjAyNi0wOS0xMFQxNDoyMjowNS40MTIrMDA6MDAifQ.4c1e0a9b7d2f"
        },
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/ContactOut"
            },
            "title": "Data",
            "type": "array"
          },
          "has_more": {
            "default": false,
            "title": "Has More",
            "type": "boolean"
          },
          "next_cursor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Pass as `cursor` to get the next page. Null at the end.",
            "title": "Next Cursor"
          }
        },
        "title": "ContactPage",
        "type": "object"
      },
      "ContactUpdateIn": {
        "description": "Only the fields you send change. Send an empty string to clear email\nor phone_number.",
        "example": {
          "email": "dana@whitfieldhomes.example.com",
          "last_name": "Whitfield-Moore",
          "phone_number": "5125550199"
        },
        "properties": {
          "email": {
            "anyOf": [
              {
                "maxLength": 255,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Email"
          },
          "first_name": {
            "anyOf": [
              {
                "maxLength": 50,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "First Name"
          },
          "last_name": {
            "anyOf": [
              {
                "maxLength": 50,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Name"
          },
          "phone_number": {
            "anyOf": [
              {
                "maxLength": 15,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Up to 15 characters. Digits only is safest, such as 5125550147 or +442079460958.",
            "title": "Phone Number"
          }
        },
        "title": "ContactUpdateIn",
        "type": "object"
      },
      "CustomFieldOut": {
        "description": "One of the account's own job fields.",
        "example": {
          "id": "9e2b7c41-4c1f-4e2a-9f6c-8b1d2e3f4a5b",
          "name": "How did you hear about us?",
          "options": [
            "Referral",
            "Google",
            "Home show",
            "Repeat customer"
          ],
          "type": "dropdown_single"
        },
        "properties": {
          "id": {
            "description": "Pass this as `field_id` when creating a lead.",
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "name": {
            "description": "The field's label, as the account set it.",
            "title": "Name",
            "type": "string"
          },
          "options": {
            "anyOf": [
              {
                "items": {},
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "The allowed values, for fields that have a fixed list.",
            "title": "Options"
          },
          "type": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "One of: string, integer, float, percent, boolean, date, datetime, time, phone, email, dropdown_single, dropdown_multiple. See Field formats on the overview for what each one accepts.",
            "title": "Type"
          }
        },
        "required": [
          "id",
          "name"
        ],
        "title": "CustomFieldOut",
        "type": "object"
      },
      "CustomFieldValueIn": {
        "description": "A value for one of the account's own job fields.\n\nGet the ids from `GET /v1/custom-fields`. A field that has since been\ndisabled or renamed is reported in the response's `warnings` rather than\nfailing the whole lead.",
        "example": {
          "field_id": "9e2b7c41-4c1f-4e2a-9f6c-8b1d2e3f4a5b",
          "value": "Referral"
        },
        "properties": {
          "field_id": {
            "description": "The field's id, from GET /v1/custom-fields.",
            "format": "uuid",
            "title": "Field Id",
            "type": "string"
          },
          "value": {
            "description": "The value, as text. See Field formats on the overview for what each field type expects. A value the field will not accept is dropped and reported in the response's warnings; the lead is still created.",
            "maxLength": 255,
            "title": "Value",
            "type": "string"
          }
        },
        "required": [
          "field_id",
          "value"
        ],
        "title": "CustomFieldValueIn",
        "type": "object"
      },
      "CustomFieldValueOut": {
        "properties": {
          "field_id": {
            "format": "uuid",
            "title": "Field Id",
            "type": "string"
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name"
          },
          "value": {
            "title": "Value"
          }
        },
        "required": [
          "field_id"
        ],
        "title": "CustomFieldValueOut",
        "type": "object"
      },
      "DeliveryDetailOut": {
        "example": {
          "attempt": 1,
          "attempts": [
            {
              "attempt": 1,
              "http_status": 200,
              "manual": false,
              "response_excerpt": "ok",
              "response_ms": 140,
              "sent_at": "2026-10-06T15:00:00Z",
              "status": "delivered"
            }
          ],
          "created_at": "2026-10-06T15:00:00Z",
          "delivered_at": "2026-10-06T15:00:01Z",
          "endpoint_url": "https://hooks.example.com/woodsystems",
          "event_id": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
          "event_type": "job.status_changed",
          "http_status": 200,
          "id": "8f7e6d5c-4b3a-4291-8a7b-6c5d4e3f2a1b",
          "max_attempts": 7,
          "request_body": "{\"api_version\":\"v1\",\"type\":\"job.status_changed\"}",
          "response_ms": 140,
          "status": "delivered"
        },
        "properties": {
          "attempt": {
            "title": "Attempt",
            "type": "integer"
          },
          "attempts": {
            "items": {
              "$ref": "#/components/schemas/AttemptOut"
            },
            "title": "Attempts",
            "type": "array"
          },
          "created_at": {
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "delivered_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Delivered At"
          },
          "endpoint_url": {
            "title": "Endpoint Url",
            "type": "string"
          },
          "error": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Error"
          },
          "event_id": {
            "format": "uuid",
            "title": "Event Id",
            "type": "string"
          },
          "event_type": {
            "title": "Event Type",
            "type": "string"
          },
          "http_status": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Http Status"
          },
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "max_attempts": {
            "title": "Max Attempts",
            "type": "integer"
          },
          "next_attempt_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Next Attempt At"
          },
          "request_body": {
            "description": "The exact body that was signed and sent.",
            "title": "Request Body",
            "type": "string"
          },
          "response_ms": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Response Ms"
          },
          "status": {
            "description": "pending, sending, delivered, failed (will retry) or dead (gave up).",
            "title": "Status",
            "type": "string"
          }
        },
        "required": [
          "id",
          "event_id",
          "event_type",
          "status",
          "attempt",
          "max_attempts",
          "created_at",
          "endpoint_url",
          "request_body"
        ],
        "title": "DeliveryDetailOut",
        "type": "object"
      },
      "DeliveryOut": {
        "example": {
          "attempt": 2,
          "created_at": "2026-10-06T15:00:00Z",
          "error": "timed out",
          "event_id": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
          "event_type": "job.status_changed",
          "http_status": 503,
          "id": "8f7e6d5c-4b3a-4291-8a7b-6c5d4e3f2a1b",
          "max_attempts": 7,
          "next_attempt_at": "2026-10-06T15:35:00Z",
          "response_ms": 10000,
          "status": "failed"
        },
        "properties": {
          "attempt": {
            "title": "Attempt",
            "type": "integer"
          },
          "created_at": {
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "delivered_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Delivered At"
          },
          "error": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Error"
          },
          "event_id": {
            "format": "uuid",
            "title": "Event Id",
            "type": "string"
          },
          "event_type": {
            "title": "Event Type",
            "type": "string"
          },
          "http_status": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Http Status"
          },
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "max_attempts": {
            "title": "Max Attempts",
            "type": "integer"
          },
          "next_attempt_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Next Attempt At"
          },
          "response_ms": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Response Ms"
          },
          "status": {
            "description": "pending, sending, delivered, failed (will retry) or dead (gave up).",
            "title": "Status",
            "type": "string"
          }
        },
        "required": [
          "id",
          "event_id",
          "event_type",
          "status",
          "attempt",
          "max_attempts",
          "created_at"
        ],
        "title": "DeliveryOut",
        "type": "object"
      },
      "DeliveryPage": {
        "example": {
          "data": [],
          "has_more": false
        },
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/DeliveryOut"
            },
            "title": "Data",
            "type": "array"
          },
          "has_more": {
            "default": false,
            "title": "Has More",
            "type": "boolean"
          },
          "next_cursor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Pass as `cursor` to get the next page. Null at the end.",
            "title": "Next Cursor"
          }
        },
        "title": "DeliveryPage",
        "type": "object"
      },
      "DepartmentOut": {
        "example": {
          "color": "#5b7f3a",
          "id": "5d4c3b2a-1908-4f7e-8d6c-5b4a39281706",
          "is_install": false,
          "is_production": true,
          "name": "Assembly"
        },
        "properties": {
          "color": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Color"
          },
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "is_install": {
            "default": false,
            "title": "Is Install",
            "type": "boolean"
          },
          "is_production": {
            "default": false,
            "title": "Is Production",
            "type": "boolean"
          },
          "name": {
            "title": "Name",
            "type": "string"
          }
        },
        "required": [
          "id",
          "name"
        ],
        "title": "DepartmentOut",
        "type": "object"
      },
      "DocumentStatusRef": {
        "description": "A document's status. `locks_editing` true means the document was sent\nor signed: the API will refuse to change it (ERR_LOCKED).",
        "example": {
          "id": "6c2d1e0f-3a4b-4c5d-8e9f-0a1b2c3d4e5f",
          "locks_editing": false,
          "name": "Draft"
        },
        "properties": {
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "locks_editing": {
            "default": false,
            "title": "Locks Editing",
            "type": "boolean"
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name"
          }
        },
        "required": [
          "id"
        ],
        "title": "DocumentStatusRef",
        "type": "object"
      },
      "EmailIn": {
        "example": {
          "body": "Hi Dana,\n\nWe are booked to install on Monday the 12th, starting at 8am.\n\nRob",
          "contact_ids": [
            "b2d4e6f8-1a3c-5e7b-9d0f-2a4c6e8b0d1f"
          ],
          "file_ids": [
            "c4b3a291-8f7e-4d6c-b5a4-93827160f5e4"
          ],
          "subject": "Your install date"
        },
        "properties": {
          "body": {
            "description": "Plain text. Line breaks are kept.",
            "maxLength": 100000,
            "minLength": 1,
            "title": "Body",
            "type": "string"
          },
          "contact_ids": {
            "description": "Contacts on the job, from GET /v1/jobs/{id}.",
            "items": {
              "format": "uuid",
              "type": "string"
            },
            "maxItems": 50,
            "minItems": 1,
            "title": "Contact Ids",
            "type": "array"
          },
          "file_ids": {
            "description": "Files on the same job to attach, from GET /v1/jobs/{id}/files.",
            "items": {
              "format": "uuid",
              "type": "string"
            },
            "maxItems": 20,
            "title": "File Ids",
            "type": "array"
          },
          "subject": {
            "maxLength": 255,
            "minLength": 1,
            "title": "Subject",
            "type": "string"
          }
        },
        "required": [
          "contact_ids",
          "subject",
          "body"
        ],
        "title": "EmailIn",
        "type": "object"
      },
      "EmailMessageOut": {
        "properties": {
          "id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Id"
          },
          "sent_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Sent At"
          },
          "status": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "delivered once the mailbox accepted it.",
            "title": "Status"
          }
        },
        "title": "EmailMessageOut",
        "type": "object"
      },
      "EmailRecipientOut": {
        "properties": {
          "email": {
            "title": "Email",
            "type": "string"
          },
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name"
          }
        },
        "required": [
          "id",
          "email"
        ],
        "title": "EmailRecipientOut",
        "type": "object"
      },
      "EmailSentOut": {
        "example": {
          "category": "project_update",
          "channel": "email",
          "created_at": "2026-10-05T16:40:00+00:00",
          "file_ids": [
            "c4b3a291-8f7e-4d6c-b5a4-93827160f5e4"
          ],
          "has_customer_reply": false,
          "id": "6b5a4c3d-2e1f-4a0b-9c8d-7e6f5a4b3c2d",
          "last_message_at": "2026-10-06T14:02:11+00:00",
          "message": {
            "id": "0a9b8c7d-6e5f-4a3b-2c1d-0e9f8a7b6c5d",
            "sent_at": "2026-10-06T14:02:11+00:00",
            "status": "delivered"
          },
          "message_count": 1,
          "subject": "Your install date",
          "to": [
            {
              "email": "dana.whitfield@example.com",
              "id": "b2d4e6f8-1a3c-5e7b-9d0f-2a4c6e8b0d1f",
              "name": "Dana Whitfield"
            }
          ]
        },
        "properties": {
          "archived_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Archived At"
          },
          "category": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "project_update for one sent through the API; estimate, invoice, payment, work_order, calendar or signature_packet for the app's own.",
            "title": "Category"
          },
          "channel": {
            "description": "email or sms.",
            "title": "Channel",
            "type": "string"
          },
          "created_at": {
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "file_ids": {
            "items": {
              "format": "uuid",
              "type": "string"
            },
            "title": "File Ids",
            "type": "array"
          },
          "has_customer_reply": {
            "default": false,
            "title": "Has Customer Reply",
            "type": "boolean"
          },
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "last_message_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Message At"
          },
          "message": {
            "$ref": "#/components/schemas/EmailMessageOut"
          },
          "message_count": {
            "default": 0,
            "title": "Message Count",
            "type": "integer"
          },
          "subject": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Subject"
          },
          "to": {
            "items": {
              "$ref": "#/components/schemas/EmailRecipientOut"
            },
            "title": "To",
            "type": "array"
          }
        },
        "required": [
          "id",
          "channel",
          "created_at",
          "message"
        ],
        "title": "EmailSentOut",
        "type": "object"
      },
      "EndpointIn": {
        "example": {
          "description": "Sync jobs to our ERP",
          "event_types": [
            "job.created",
            "job.status_changed"
          ],
          "url": "https://hooks.example.com/woodsystems"
        },
        "properties": {
          "description": {
            "anyOf": [
              {
                "maxLength": 200,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description"
          },
          "event_types": {
            "description": "Event types, or [\"*\"] for every event.",
            "items": {
              "type": "string"
            },
            "title": "Event Types",
            "type": "array"
          },
          "url": {
            "description": "https only. Private and internal addresses are refused.",
            "maxLength": 2048,
            "minLength": 8,
            "title": "Url",
            "type": "string"
          }
        },
        "required": [
          "url"
        ],
        "title": "EndpointIn",
        "type": "object"
      },
      "EndpointOut": {
        "example": {
          "api_version": "v1",
          "consecutive_failures": 0,
          "created_at": "2026-10-06T14:00:00Z",
          "description": "Sync jobs to our ERP",
          "event_types": [
            "job.created",
            "job.status_changed"
          ],
          "failures_last_24h": 0,
          "id": "6d1f0a2b-3c4d-4e5f-8a9b-0c1d2e3f4a5b",
          "is_active": true,
          "last_delivery_at": "2026-10-06T15:12:00Z",
          "last_success_at": "2026-10-06T15:12:00Z",
          "url": "https://hooks.example.com/woodsystems"
        },
        "properties": {
          "api_version": {
            "title": "Api Version",
            "type": "string"
          },
          "consecutive_failures": {
            "default": 0,
            "title": "Consecutive Failures",
            "type": "integer"
          },
          "created_at": {
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description"
          },
          "disabled_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Disabled At"
          },
          "disabled_reason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "manual, consecutive_failures, or gone (the receiver answered 410).",
            "title": "Disabled Reason"
          },
          "event_types": {
            "items": {
              "type": "string"
            },
            "title": "Event Types",
            "type": "array"
          },
          "failures_last_24h": {
            "default": 0,
            "title": "Failures Last 24H",
            "type": "integer"
          },
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "is_active": {
            "title": "Is Active",
            "type": "boolean"
          },
          "last_delivery_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Delivery At"
          },
          "last_success_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Success At"
          },
          "url": {
            "title": "Url",
            "type": "string"
          }
        },
        "required": [
          "id",
          "url",
          "event_types",
          "is_active",
          "api_version",
          "created_at"
        ],
        "title": "EndpointOut",
        "type": "object"
      },
      "EndpointUpdateIn": {
        "example": {
          "event_types": [
            "*"
          ],
          "is_active": true
        },
        "properties": {
          "description": {
            "anyOf": [
              {
                "maxLength": 200,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description"
          },
          "event_types": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Event Types"
          },
          "is_active": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "Switching an endpoint back on clears its failure record.",
            "title": "Is Active"
          },
          "url": {
            "anyOf": [
              {
                "maxLength": 2048,
                "minLength": 8,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Url"
          }
        },
        "title": "EndpointUpdateIn",
        "type": "object"
      },
      "EndpointWithSecretOut": {
        "example": {
          "api_version": "v1",
          "consecutive_failures": 0,
          "created_at": "2026-10-06T14:00:00Z",
          "description": "Sync jobs to our ERP",
          "event_types": [
            "job.created",
            "job.status_changed"
          ],
          "failures_last_24h": 0,
          "id": "6d1f0a2b-3c4d-4e5f-8a9b-0c1d2e3f4a5b",
          "is_active": true,
          "last_delivery_at": "2026-10-06T15:12:00Z",
          "last_success_at": "2026-10-06T15:12:00Z",
          "secret": "whsec_4yR8u0Wm2h9kQ1zX6cV3bN7mL5pJ0sD2fG4hK8lQ",
          "url": "https://hooks.example.com/woodsystems"
        },
        "properties": {
          "api_version": {
            "title": "Api Version",
            "type": "string"
          },
          "consecutive_failures": {
            "default": 0,
            "title": "Consecutive Failures",
            "type": "integer"
          },
          "created_at": {
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description"
          },
          "disabled_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Disabled At"
          },
          "disabled_reason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "manual, consecutive_failures, or gone (the receiver answered 410).",
            "title": "Disabled Reason"
          },
          "event_types": {
            "items": {
              "type": "string"
            },
            "title": "Event Types",
            "type": "array"
          },
          "failures_last_24h": {
            "default": 0,
            "title": "Failures Last 24H",
            "type": "integer"
          },
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "is_active": {
            "title": "Is Active",
            "type": "boolean"
          },
          "last_delivery_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Delivery At"
          },
          "last_success_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Success At"
          },
          "secret": {
            "description": "Shown on create and rotate. Use it to verify the WoodSystems-Signature header.",
            "title": "Secret",
            "type": "string"
          },
          "url": {
            "title": "Url",
            "type": "string"
          }
        },
        "required": [
          "id",
          "url",
          "event_types",
          "is_active",
          "api_version",
          "created_at",
          "secret"
        ],
        "title": "EndpointWithSecretOut",
        "type": "object"
      },
      "EstimateCreateIn": {
        "example": {
          "deposit_amount": "30",
          "deposit_is_percentage": true,
          "expiration_date": "2026-10-31",
          "job_id": "3f9a1c77-5e3b-4a02-9d8e-2c7b6a1f0e4d",
          "name": "Whitfield kitchen",
          "notes": "Thanks for having us out. Pricing holds for 30 days.",
          "terms": "50% deposit, balance on install."
        },
        "properties": {
          "deposit_amount": {
            "anyOf": [
              {
                "minimum": 0.0,
                "type": "number"
              },
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Deposit Amount"
          },
          "deposit_is_percentage": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "True: deposit_amount is a percent of the total.",
            "title": "Deposit Is Percentage"
          },
          "estimate_date": {
            "anyOf": [
              {
                "format": "date",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Estimate Date"
          },
          "expiration_date": {
            "anyOf": [
              {
                "format": "date",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Expiration Date"
          },
          "internal_notes": {
            "anyOf": [
              {
                "maxLength": 10000,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Internal Notes"
          },
          "job_id": {
            "description": "From GET /v1/jobs.",
            "format": "uuid",
            "title": "Job Id",
            "type": "string"
          },
          "name": {
            "maxLength": 255,
            "minLength": 1,
            "title": "Name",
            "type": "string"
          },
          "notes": {
            "anyOf": [
              {
                "maxLength": 10000,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Notes"
          },
          "status_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "A status that does not lock editing, from GET /v1/meta/estimate-statuses. Defaults to the account's default (Draft).",
            "title": "Status Id"
          },
          "terms": {
            "anyOf": [
              {
                "maxLength": 10000,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Terms"
          }
        },
        "required": [
          "job_id",
          "name"
        ],
        "title": "EstimateCreateIn",
        "type": "object"
      },
      "EstimateOut": {
        "example": {
          "created_at": "2026-10-01T15:04:00Z",
          "currency": "USD",
          "deposit_amount": "30",
          "deposit_is_percentage": true,
          "estimate_date": "2026-10-01",
          "expiration_date": "2026-10-31",
          "id": "4d3c2b1a-0f9e-4d8c-8b7a-6f5e4d3c2b1a",
          "is_primary": true,
          "job": {
            "id": "3f9a1c77-5e3b-4a02-9d8e-2c7b6a1f0e4d",
            "name": "Whitfield kitchen remodel"
          },
          "lines": [
            {
              "created_at": "2026-10-01T15:06:12Z",
              "currency": "USD",
              "description": "Maple, shaker door",
              "estimate_id": "4d3c2b1a-0f9e-4d8c-8b7a-6f5e4d3c2b1a",
              "id": "1f2e3d4c-5b6a-4798-8a7b-6c5d4e3f2a1b",
              "is_discount": false,
              "name": "Base cabinet, 36 inch",
              "order": 1,
              "quantity": "3",
              "section_id": "9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
              "taxable": true,
              "total": "1234.50",
              "unit": {
                "id": "2b3c4d5e-6f70-4182-9a3b-4c5d6e7f8091",
                "name": "Each"
              },
              "unit_cost": "240.00",
              "unit_price": "411.50",
              "updated_at": "2026-10-01T15:06:12Z"
            }
          ],
          "name": "Whitfield kitchen",
          "notes": "Thanks for having us out. Pricing holds for 30 days.",
          "reference": "E60",
          "revision": "A",
          "sections": [
            {
              "created_at": "2026-10-01T15:04:00Z",
              "estimate_id": "4d3c2b1a-0f9e-4d8c-8b7a-6f5e4d3c2b1a",
              "id": "9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
              "name": "Kitchen cabinets",
              "order": 1,
              "updated_at": "2026-10-01T15:04:00Z"
            }
          ],
          "status": {
            "id": "6c2d1e0f-3a4b-4c5d-8e9f-0a1b2c3d4e5f",
            "locks_editing": false,
            "name": "Draft"
          },
          "subtotal": "1234.50",
          "tax_rate": "8.25",
          "terms": "50% deposit, balance on install.",
          "total": "1336.35",
          "updated_at": "2026-10-01T15:06:12Z"
        },
        "properties": {
          "accepted_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Accepted At"
          },
          "created_at": {
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "currency": {
            "default": "USD",
            "title": "Currency",
            "type": "string"
          },
          "deposit_amount": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "A percent when deposit_is_percentage is true, else money. Null when none is asked.",
            "title": "Deposit Amount"
          },
          "deposit_is_percentage": {
            "default": false,
            "title": "Deposit Is Percentage",
            "type": "boolean"
          },
          "estimate_date": {
            "anyOf": [
              {
                "format": "date",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Estimate Date"
          },
          "expiration_date": {
            "anyOf": [
              {
                "format": "date",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Expiration Date"
          },
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "internal_notes": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Never shown to the customer.",
            "title": "Internal Notes"
          },
          "is_primary": {
            "default": false,
            "title": "Is Primary",
            "type": "boolean"
          },
          "job": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Ref"
              },
              {
                "type": "null"
              }
            ]
          },
          "lines": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/LineOut"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "With include=lines. Every line, each naming its section_id.",
            "title": "Lines"
          },
          "name": {
            "title": "Name",
            "type": "string"
          },
          "notes": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Shown to the customer on the estimate.",
            "title": "Notes"
          },
          "reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The estimate number people use, e.g. E60.",
            "title": "Reference"
          },
          "revision": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The revision letter: A, then B for the first revision.",
            "title": "Revision"
          },
          "sections": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/SectionOut"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "With include=sections.",
            "title": "Sections"
          },
          "status": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/DocumentStatusRef"
              },
              {
                "type": "null"
              }
            ]
          },
          "subtotal": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Lines before tax, a decimal string.",
            "title": "Subtotal"
          },
          "tax_rate": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Percent, e.g. \"8.25\".",
            "title": "Tax Rate"
          },
          "terms": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Terms"
          },
          "total": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Lines plus tax, a decimal string.",
            "title": "Total"
          },
          "updated_at": {
            "format": "date-time",
            "title": "Updated At",
            "type": "string"
          }
        },
        "required": [
          "id",
          "name",
          "created_at",
          "updated_at"
        ],
        "title": "EstimateOut",
        "type": "object"
      },
      "EstimatePage": {
        "example": {
          "data": [
            {
              "created_at": "2026-10-01T15:04:00Z",
              "currency": "USD",
              "deposit_amount": "30",
              "deposit_is_percentage": true,
              "estimate_date": "2026-10-01",
              "expiration_date": "2026-10-31",
              "id": "4d3c2b1a-0f9e-4d8c-8b7a-6f5e4d3c2b1a",
              "is_primary": true,
              "job": {
                "id": "3f9a1c77-5e3b-4a02-9d8e-2c7b6a1f0e4d",
                "name": "Whitfield kitchen remodel"
              },
              "name": "Whitfield kitchen",
              "notes": "Thanks for having us out. Pricing holds for 30 days.",
              "reference": "E60",
              "revision": "A",
              "status": {
                "id": "6c2d1e0f-3a4b-4c5d-8e9f-0a1b2c3d4e5f",
                "locks_editing": false,
                "name": "Draft"
              },
              "subtotal": "1234.50",
              "tax_rate": "8.25",
              "terms": "50% deposit, balance on install.",
              "total": "1336.35",
              "updated_at": "2026-10-01T15:06:12Z"
            }
          ],
          "has_more": true,
          "next_cursor": "eyJ2IjoiMjAyNi0xMC0wMVQxNTowNDowMCswMDowMCJ9.4c1e0a9b7d2f"
        },
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/EstimateOut"
            },
            "title": "Data",
            "type": "array"
          },
          "has_more": {
            "default": false,
            "title": "Has More",
            "type": "boolean"
          },
          "next_cursor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Pass as `cursor` to get the next page. Null at the end.",
            "title": "Next Cursor"
          }
        },
        "title": "EstimatePage",
        "type": "object"
      },
      "EstimateSendIn": {
        "example": {
          "contact_ids": [
            "b2d4e6f8-1a3c-5e7b-9d0f-2a4c6e8b0d1f"
          ],
          "message": "Hi Dana, here is the estimate we talked through on Tuesday.",
          "request_approval": true,
          "subject": "Your kitchen estimate"
        },
        "properties": {
          "contact_ids": {
            "description": "Contacts of this account, from GET /v1/contacts. Each gets their own email and link.",
            "items": {
              "format": "uuid",
              "type": "string"
            },
            "maxItems": 20,
            "minItems": 1,
            "title": "Contact Ids",
            "type": "array"
          },
          "message": {
            "anyOf": [
              {
                "maxLength": 10000,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Shown above the link in the email.",
            "title": "Message"
          },
          "request_approval": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "Show the customer an Accept button on the estimate page. Left out, the estimate keeps its current setting.",
            "title": "Request Approval"
          },
          "subject": {
            "anyOf": [
              {
                "maxLength": 255,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Subject"
          }
        },
        "required": [
          "contact_ids"
        ],
        "title": "EstimateSendIn",
        "type": "object"
      },
      "EstimateUpdateIn": {
        "description": "Only the fields you send change.",
        "example": {
          "expiration_date": "2026-11-15",
          "name": "Whitfield kitchen and laundry"
        },
        "properties": {
          "deposit_amount": {
            "anyOf": [
              {
                "minimum": 0.0,
                "type": "number"
              },
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Deposit Amount"
          },
          "deposit_is_percentage": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Deposit Is Percentage"
          },
          "estimate_date": {
            "anyOf": [
              {
                "format": "date",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Estimate Date"
          },
          "expiration_date": {
            "anyOf": [
              {
                "format": "date",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Expiration Date"
          },
          "internal_notes": {
            "anyOf": [
              {
                "maxLength": 10000,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Internal Notes"
          },
          "name": {
            "anyOf": [
              {
                "maxLength": 255,
                "minLength": 1,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name"
          },
          "notes": {
            "anyOf": [
              {
                "maxLength": 10000,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Notes"
          },
          "status_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "From GET /v1/meta/estimate-statuses.",
            "title": "Status Id"
          },
          "tax_rate": {
            "anyOf": [
              {
                "maximum": 100.0,
                "minimum": 0.0,
                "type": "number"
              },
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Percent, e.g. \"8.25\".",
            "title": "Tax Rate"
          },
          "terms": {
            "anyOf": [
              {
                "maxLength": 10000,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Terms"
          }
        },
        "title": "EstimateUpdateIn",
        "type": "object"
      },
      "EventCreateIn": {
        "description": "A job's event names its job. An event with no job is either internal\n(a meeting) or external. At least one department or team is required;\nthe people on the event are their members.",
        "example": {
          "department_ids": [
            "5a4b3c2d-1e0f-4a9b-8c7d-6e5f4a3b2c1d"
          ],
          "description": "Bring the long ladder",
          "end": "2026-10-12T21:00:00Z",
          "job_id": "3f9a1c77-5e3b-4a02-9d8e-2c7b6a1f0e4d",
          "start": "2026-10-12T13:00:00Z",
          "title": "Install day 1"
        },
        "properties": {
          "all_day": {
            "default": false,
            "title": "All Day",
            "type": "boolean"
          },
          "color": {
            "anyOf": [
              {
                "pattern": "^#[0-9A-Fa-f]{6}$",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Hex colour, e.g. #336699.",
            "title": "Color"
          },
          "department_ids": {
            "description": "From GET /v1/meta/departments. The first sets the colour.",
            "items": {
              "format": "uuid",
              "type": "string"
            },
            "title": "Department Ids",
            "type": "array"
          },
          "description": {
            "anyOf": [
              {
                "maxLength": 255,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description"
          },
          "end": {
            "format": "date-time",
            "title": "End",
            "type": "string"
          },
          "is_external": {
            "default": false,
            "title": "Is External",
            "type": "boolean"
          },
          "is_internal": {
            "default": false,
            "title": "Is Internal",
            "type": "boolean"
          },
          "job_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Required unless is_internal or is_external is true.",
            "title": "Job Id"
          },
          "start": {
            "description": "RFC 3339 with an offset. Timed events must fall inside the account's office hours.",
            "format": "date-time",
            "title": "Start",
            "type": "string"
          },
          "team_ids": {
            "description": "Teams must belong to one of the departments given.",
            "items": {
              "format": "uuid",
              "type": "string"
            },
            "title": "Team Ids",
            "type": "array"
          },
          "title": {
            "maxLength": 255,
            "minLength": 1,
            "title": "Title",
            "type": "string"
          }
        },
        "required": [
          "title",
          "start",
          "end"
        ],
        "title": "EventCreateIn",
        "type": "object"
      },
      "EventJobRef": {
        "properties": {
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name"
          },
          "reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The job number people use, e.g. J1042.",
            "title": "Reference"
          }
        },
        "required": [
          "id"
        ],
        "title": "EventJobRef",
        "type": "object"
      },
      "EventOut": {
        "example": {
          "all_day": false,
          "assignees": [
            {
              "id": "e1d2c3b4-a596-4877-8695-a4b3c2d1e0f9",
              "name": "Cal Crew"
            }
          ],
          "color": "#336699",
          "created_at": "2026-10-01T15:04:00+00:00",
          "departments": [
            {
              "id": "5a4b3c2d-1e0f-4a9b-8c7d-6e5f4a3b2c1d",
              "name": "Install"
            }
          ],
          "description": "Bring the long ladder",
          "end": "2026-10-12T21:00:00+00:00",
          "from_timeline": true,
          "id": "9d2c4b6a-1e3f-4a5b-8c7d-6e5f4a3b2c1d",
          "is_external": false,
          "is_internal": false,
          "job": {
            "id": "3f9a1c77-5e3b-4a02-9d8e-2c7b6a1f0e4d",
            "name": "Whitfield kitchen remodel",
            "reference": "J1042"
          },
          "start": "2026-10-12T13:00:00+00:00",
          "teams": [],
          "tentative": false,
          "title": "Install day 1",
          "updated_at": "2026-10-05T09:12:44+00:00"
        },
        "properties": {
          "all_day": {
            "default": false,
            "title": "All Day",
            "type": "boolean"
          },
          "assignees": {
            "description": "The people on the event: the members of its departments and teams.",
            "items": {
              "$ref": "#/components/schemas/Ref"
            },
            "title": "Assignees",
            "type": "array"
          },
          "color": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Hex colour, from the first department unless one was set.",
            "title": "Color"
          },
          "created_at": {
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "departments": {
            "items": {
              "$ref": "#/components/schemas/Ref"
            },
            "title": "Departments",
            "type": "array"
          },
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description"
          },
          "end": {
            "format": "date-time",
            "title": "End",
            "type": "string"
          },
          "from_timeline": {
            "default": false,
            "description": "Made by the job's timeline rather than by a person.",
            "title": "From Timeline",
            "type": "boolean"
          },
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "is_external": {
            "default": false,
            "description": "An event with people outside the company and no job.",
            "title": "Is External",
            "type": "boolean"
          },
          "is_internal": {
            "default": false,
            "description": "A meeting, training or maintenance event with no job.",
            "title": "Is Internal",
            "type": "boolean"
          },
          "job": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/EventJobRef"
              },
              {
                "type": "null"
              }
            ],
            "description": "The job the event is for. Null for an internal or external event."
          },
          "start": {
            "format": "date-time",
            "title": "Start",
            "type": "string"
          },
          "teams": {
            "items": {
              "$ref": "#/components/schemas/Ref"
            },
            "title": "Teams",
            "type": "array"
          },
          "tentative": {
            "default": false,
            "description": "Part of a job's rough plan: the job's dates are not confirmed yet. Only its times and description can change, and it cannot be deleted (ERR_LOCKED).",
            "title": "Tentative",
            "type": "boolean"
          },
          "title": {
            "title": "Title",
            "type": "string"
          },
          "updated_at": {
            "format": "date-time",
            "title": "Updated At",
            "type": "string"
          },
          "work_order": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Ref"
              },
              {
                "type": "null"
              }
            ],
            "description": "The work order the event books, when it names one."
          }
        },
        "required": [
          "id",
          "title",
          "start",
          "end",
          "created_at",
          "updated_at"
        ],
        "title": "EventOut",
        "type": "object"
      },
      "EventTypeOut": {
        "example": {
          "description": "A job moved to another main status or phase.",
          "object": "job",
          "type": "job.status_changed"
        },
        "properties": {
          "description": {
            "title": "Description",
            "type": "string"
          },
          "object": {
            "title": "Object",
            "type": "string"
          },
          "type": {
            "title": "Type",
            "type": "string"
          }
        },
        "required": [
          "type",
          "object",
          "description"
        ],
        "title": "EventTypeOut",
        "type": "object"
      },
      "EventUpdateIn": {
        "description": "Only the fields you send change. Sending department_ids or team_ids\nreplaces the whole list.",
        "example": {
          "description": "Moved a day for the countertop delivery",
          "end": "2026-10-13T21:00:00Z",
          "start": "2026-10-13T13:00:00Z"
        },
        "properties": {
          "all_day": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "All Day"
          },
          "color": {
            "anyOf": [
              {
                "pattern": "^#[0-9A-Fa-f]{6}$",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Color"
          },
          "department_ids": {
            "anyOf": [
              {
                "items": {
                  "format": "uuid",
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Department Ids"
          },
          "description": {
            "anyOf": [
              {
                "maxLength": 255,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description"
          },
          "end": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "End"
          },
          "is_external": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Is External"
          },
          "is_internal": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Is Internal"
          },
          "job_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Job Id"
          },
          "start": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Start"
          },
          "team_ids": {
            "anyOf": [
              {
                "items": {
                  "format": "uuid",
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Team Ids"
          },
          "title": {
            "anyOf": [
              {
                "maxLength": 255,
                "minLength": 1,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Title"
          }
        },
        "title": "EventUpdateIn",
        "type": "object"
      },
      "FileOut": {
        "example": {
          "content_type": "application/pdf",
          "created_at": "2026-10-05T09:12:44+00:00",
          "file_name": "Kitchen elevation.pdf",
          "folder": {
            "id": "1f2e3d4c-5b6a-4798-8a7b-6c5d4e3f2a1b",
            "name": "Drawings"
          },
          "id": "c4b3a291-8f7e-4d6c-b5a4-93827160f5e4",
          "job_id": "3f9a1c77-5e3b-4a02-9d8e-2c7b6a1f0e4d",
          "md5": "9e107d9d372bb6826bd81d3542a419d6",
          "name": "Kitchen elevation",
          "size_bytes": 482133,
          "updated_at": "2026-10-05T09:12:44+00:00",
          "uploaded_at": "2026-10-05T09:12:44+00:00"
        },
        "properties": {
          "content_type": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Content Type"
          },
          "created_at": {
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The caption shown under the preview in the app.",
            "title": "Description"
          },
          "file_name": {
            "description": "The name with its extension, as it downloads.",
            "title": "File Name",
            "type": "string"
          },
          "folder": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Ref"
              },
              {
                "type": "null"
              }
            ],
            "description": "The job folder it sits in."
          },
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "job_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Job Id"
          },
          "md5": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Hex MD5 of the stored bytes, as the storage service recorded them. Null for some older files.",
            "title": "Md5"
          },
          "name": {
            "description": "The display name, without the extension.",
            "title": "Name",
            "type": "string"
          },
          "size_bytes": {
            "title": "Size Bytes",
            "type": "integer"
          },
          "updated_at": {
            "format": "date-time",
            "title": "Updated At",
            "type": "string"
          },
          "uploaded_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Uploaded At"
          }
        },
        "required": [
          "id",
          "name",
          "file_name",
          "size_bytes",
          "created_at",
          "updated_at"
        ],
        "title": "FileOut",
        "type": "object"
      },
      "FilePage": {
        "example": {
          "data": [
            {
              "content_type": "application/pdf",
              "created_at": "2026-10-05T09:12:44+00:00",
              "file_name": "Kitchen elevation.pdf",
              "folder": {
                "id": "1f2e3d4c-5b6a-4798-8a7b-6c5d4e3f2a1b",
                "name": "Drawings"
              },
              "id": "c4b3a291-8f7e-4d6c-b5a4-93827160f5e4",
              "job_id": "3f9a1c77-5e3b-4a02-9d8e-2c7b6a1f0e4d",
              "md5": "9e107d9d372bb6826bd81d3542a419d6",
              "name": "Kitchen elevation",
              "size_bytes": 482133,
              "updated_at": "2026-10-05T09:12:44+00:00",
              "uploaded_at": "2026-10-05T09:12:44+00:00"
            }
          ],
          "has_more": true,
          "next_cursor": "eyJ2IjoiMjAyNi0xMC0wNVQwOToxMjo0NCswMDowMCJ9.4c1e0a9b7d2f"
        },
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/FileOut"
            },
            "title": "Data",
            "type": "array"
          },
          "has_more": {
            "default": false,
            "title": "Has More",
            "type": "boolean"
          },
          "next_cursor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Pass as `cursor` to get the next page. Null at the end.",
            "title": "Next Cursor"
          }
        },
        "title": "FilePage",
        "type": "object"
      },
      "FileWithLinkOut": {
        "example": {
          "content_type": "application/pdf",
          "created_at": "2026-10-05T09:12:44+00:00",
          "download_url": "https://storage.googleapis.com/ws-tenant-5c8d2e1f/job/3f9a1c77/4a1b.pdf?X-Goog-Signature=...",
          "download_url_expires_at": "2026-10-06T09:12:44+00:00",
          "file_name": "Kitchen elevation.pdf",
          "folder": {
            "id": "1f2e3d4c-5b6a-4798-8a7b-6c5d4e3f2a1b",
            "name": "Drawings"
          },
          "id": "c4b3a291-8f7e-4d6c-b5a4-93827160f5e4",
          "job_id": "3f9a1c77-5e3b-4a02-9d8e-2c7b6a1f0e4d",
          "md5": "9e107d9d372bb6826bd81d3542a419d6",
          "name": "Kitchen elevation",
          "size_bytes": 482133,
          "updated_at": "2026-10-05T09:12:44+00:00",
          "uploaded_at": "2026-10-05T09:12:44+00:00"
        },
        "properties": {
          "content_type": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Content Type"
          },
          "created_at": {
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The caption shown under the preview in the app.",
            "title": "Description"
          },
          "download_url": {
            "description": "A link that downloads the file without a credential. Valid for 24 hours; do not store it.",
            "title": "Download Url",
            "type": "string"
          },
          "download_url_expires_at": {
            "format": "date-time",
            "title": "Download Url Expires At",
            "type": "string"
          },
          "file_name": {
            "description": "The name with its extension, as it downloads.",
            "title": "File Name",
            "type": "string"
          },
          "folder": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Ref"
              },
              {
                "type": "null"
              }
            ],
            "description": "The job folder it sits in."
          },
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "job_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Job Id"
          },
          "md5": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Hex MD5 of the stored bytes, as the storage service recorded them. Null for some older files.",
            "title": "Md5"
          },
          "name": {
            "description": "The display name, without the extension.",
            "title": "Name",
            "type": "string"
          },
          "size_bytes": {
            "title": "Size Bytes",
            "type": "integer"
          },
          "updated_at": {
            "format": "date-time",
            "title": "Updated At",
            "type": "string"
          },
          "uploaded_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Uploaded At"
          }
        },
        "required": [
          "id",
          "name",
          "file_name",
          "size_bytes",
          "created_at",
          "updated_at",
          "download_url",
          "download_url_expires_at"
        ],
        "title": "FileWithLinkOut",
        "type": "object"
      },
      "FormFieldOut": {
        "description": "One settable field on a job form.",
        "properties": {
          "field_key": {
            "description": "The key to use in `form.values` or a section's `values`.",
            "title": "Field Key",
            "type": "string"
          },
          "help_text": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Guidance the account wrote for this field.",
            "title": "Help Text"
          },
          "name": {
            "description": "The field's label.",
            "title": "Name",
            "type": "string"
          },
          "options": {
            "anyOf": [
              {
                "items": {},
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Allowed values, for SELECT fields.",
            "title": "Options"
          },
          "required": {
            "default": false,
            "description": "Whether the account marked it required.",
            "title": "Required",
            "type": "boolean"
          },
          "type": {
            "description": "TEXT, TEXTAREA, NUMBER, SELECT or CHECKBOX.",
            "title": "Type",
            "type": "string"
          }
        },
        "required": [
          "field_key",
          "name",
          "type"
        ],
        "title": "FormFieldOut",
        "type": "object"
      },
      "FormIn": {
        "description": "Job form data to attach to the lead.\n\nOptional in full. An account that does not use job forms, or an integration\nthat only captures contact details, omits this and nothing is created.",
        "properties": {
          "schema_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Which form template to use, from GET /v1/job-forms. Omit to use the default set on your API key, or failing that the account's default form.",
            "title": "Schema Id"
          },
          "sections": {
            "description": "Repeated sections to create on the form, each with its own values.",
            "items": {
              "$ref": "#/components/schemas/FormSectionIn"
            },
            "title": "Sections",
            "type": "array"
          },
          "values": {
            "additionalProperties": true,
            "description": "Values for the form's non-repeating fields, keyed by `field_key`. Keys the form does not define are reported in `warnings` and skipped.",
            "title": "Values",
            "type": "object"
          }
        },
        "title": "FormIn",
        "type": "object"
      },
      "FormSchemaOut": {
        "description": "One of the account's job form templates.",
        "example": {
          "fields": [
            {
              "field_key": "budget_range",
              "name": "Budget range",
              "options": [
                "Under 10k",
                "10-25k",
                "25-50k",
                "50k+"
              ],
              "required": false,
              "type": "SELECT"
            }
          ],
          "id": "7c1e9d22-8b4a-4f31-b6d5-0e9a3c5f7b2d",
          "is_default": true,
          "name": "Website intake",
          "section_fields": [
            {
              "field_key": "cabinet_style",
              "name": "Cabinet style",
              "required": false,
              "type": "TEXT"
            }
          ],
          "section_label": "Room"
        },
        "properties": {
          "fields": {
            "description": "Fields that appear once. Send these in `form.values`.",
            "items": {
              "$ref": "#/components/schemas/FormFieldOut"
            },
            "title": "Fields",
            "type": "array"
          },
          "id": {
            "description": "Pass this as `form.schema_id` when creating a lead.",
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "is_default": {
            "description": "Whether this is the account's default form.",
            "title": "Is Default",
            "type": "boolean"
          },
          "name": {
            "description": "What the account calls this form.",
            "title": "Name",
            "type": "string"
          },
          "section_fields": {
            "description": "Fields that repeat per section. Send these in each section's `values`.",
            "items": {
              "$ref": "#/components/schemas/FormFieldOut"
            },
            "title": "Section Fields",
            "type": "array"
          },
          "section_label": {
            "description": "What the account calls a section on this form - \"Room\", \"Area\", \"Unit\". Use it as the label in your own form.",
            "title": "Section Label",
            "type": "string"
          }
        },
        "required": [
          "id",
          "name",
          "is_default",
          "section_label"
        ],
        "title": "FormSchemaOut",
        "type": "object"
      },
      "FormSectionIn": {
        "description": "One repeated section of the account's job form - a room, an area, a unit.",
        "example": {
          "name": "Kitchen",
          "values": {
            "cabinet_style": "Shaker",
            "linear_feet": 24
          }
        },
        "properties": {
          "name": {
            "description": "What to call this section.",
            "maxLength": 100,
            "minLength": 1,
            "title": "Name",
            "type": "string"
          },
          "values": {
            "additionalProperties": true,
            "description": "Values for the form's section fields, keyed by `field_key`. Get the keys from GET /v1/job-forms.",
            "title": "Values",
            "type": "object"
          }
        },
        "required": [
          "name"
        ],
        "title": "FormSectionIn",
        "type": "object"
      },
      "InvoiceCreateIn": {
        "example": {
          "due_date": "2026-11-01",
          "job_id": "3f9a1c77-5e3b-4a02-9d8e-2c7b6a1f0e4d",
          "name": "Whitfield kitchen, extras",
          "notes": "Crown moulding added on site."
        },
        "properties": {
          "due_date": {
            "format": "date",
            "title": "Due Date",
            "type": "string"
          },
          "internal_notes": {
            "anyOf": [
              {
                "maxLength": 10000,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Internal Notes"
          },
          "invoice_date": {
            "anyOf": [
              {
                "format": "date",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Invoice Date"
          },
          "job_id": {
            "description": "From GET /v1/jobs.",
            "format": "uuid",
            "title": "Job Id",
            "type": "string"
          },
          "name": {
            "maxLength": 255,
            "minLength": 1,
            "title": "Name",
            "type": "string"
          },
          "notes": {
            "anyOf": [
              {
                "maxLength": 10000,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Notes"
          },
          "terms": {
            "anyOf": [
              {
                "maxLength": 10000,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Terms"
          }
        },
        "required": [
          "job_id",
          "name",
          "due_date"
        ],
        "title": "InvoiceCreateIn",
        "type": "object"
      },
      "InvoiceFromEstimateIn": {
        "description": "`amount_mode` decides what the invoice bills:\n\n* `remaining_balance`: what is left of the estimate after its earlier invoices (the default),\n* `full`: the estimate's whole total,\n* `percentage`: `percentage` percent of the estimate's total,\n* `amount`: exactly `amount`.",
        "example": {
          "amount_mode": "percentage",
          "due_date": "2026-11-01",
          "percentage": "50"
        },
        "properties": {
          "amount": {
            "anyOf": [
              {
                "exclusiveMinimum": 0.0,
                "type": "number"
              },
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Amount"
          },
          "amount_mode": {
            "default": "remaining_balance",
            "enum": [
              "remaining_balance",
              "full",
              "percentage",
              "amount"
            ],
            "title": "Amount Mode",
            "type": "string"
          },
          "due_date": {
            "format": "date",
            "title": "Due Date",
            "type": "string"
          },
          "name": {
            "anyOf": [
              {
                "maxLength": 255,
                "minLength": 1,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Defaults to the estimate's name.",
            "title": "Name"
          },
          "percentage": {
            "anyOf": [
              {
                "exclusiveMinimum": 0.0,
                "maximum": 100.0,
                "type": "number"
              },
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Percentage"
          }
        },
        "required": [
          "due_date"
        ],
        "title": "InvoiceFromEstimateIn",
        "type": "object"
      },
      "InvoiceLineCreateIn": {
        "example": {
          "name": "Crown moulding",
          "quantity": "2",
          "taxable": true,
          "unit_price": "617.25"
        },
        "properties": {
          "description": {
            "anyOf": [
              {
                "maxLength": 10000,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description"
          },
          "name": {
            "maxLength": 255,
            "minLength": 1,
            "title": "Name",
            "type": "string"
          },
          "product_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "From GET /v1/products. Sets the unit; the price is the one you send.",
            "title": "Product Id"
          },
          "quantity": {
            "anyOf": [
              {
                "exclusiveMinimum": 0.0,
                "type": "number"
              },
              {
                "type": "string"
              }
            ],
            "title": "Quantity"
          },
          "taxable": {
            "default": false,
            "title": "Taxable",
            "type": "boolean"
          },
          "unit_cost": {
            "anyOf": [
              {
                "minimum": 0.0,
                "type": "number"
              },
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Unit Cost"
          },
          "unit_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "From GET /v1/meta/units. Defaults to the product's unit, or Each.",
            "title": "Unit Id"
          },
          "unit_price": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "string"
              }
            ],
            "title": "Unit Price"
          }
        },
        "required": [
          "name",
          "quantity",
          "unit_price"
        ],
        "title": "InvoiceLineCreateIn",
        "type": "object"
      },
      "InvoiceOut": {
        "example": {
          "amount_due": "668.18",
          "balance": "668.18",
          "created_at": "2026-10-02T10:00:00Z",
          "currency": "USD",
          "due_date": "2026-11-01",
          "estimate": {
            "id": "4d3c2b1a-0f9e-4d8c-8b7a-6f5e4d3c2b1a",
            "name": "Whitfield kitchen"
          },
          "id": "7e6d5c4b-3a29-4180-9f7e-6d5c4b3a2918",
          "invoice_date": "2026-10-02",
          "job": {
            "id": "3f9a1c77-5e3b-4a02-9d8e-2c7b6a1f0e4d",
            "name": "Whitfield kitchen remodel"
          },
          "name": "Whitfield kitchen, deposit",
          "notes": "Deposit to schedule production.",
          "reference": "I41",
          "status": {
            "id": "5b4a3928-1706-4f5e-8d4c-3b2a19087f6e",
            "locks_editing": false,
            "name": "Open"
          },
          "tax_rate": "8.25",
          "terms": "Net 30",
          "total": "1336.35",
          "updated_at": "2026-10-02T10:00:00Z"
        },
        "properties": {
          "amount_due": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "What this invoice bills: the total, or part of it for a deposit or progress invoice.",
            "title": "Amount Due"
          },
          "balance": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "amount_due less received payments applied to it.",
            "title": "Balance"
          },
          "created_at": {
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "currency": {
            "default": "USD",
            "title": "Currency",
            "type": "string"
          },
          "due_date": {
            "anyOf": [
              {
                "format": "date",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Due Date"
          },
          "estimate": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Ref"
              },
              {
                "type": "null"
              }
            ],
            "description": "The estimate it was made from, if any."
          },
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "internal_notes": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Never shown to the customer.",
            "title": "Internal Notes"
          },
          "invoice_date": {
            "anyOf": [
              {
                "format": "date",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Invoice Date"
          },
          "job": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Ref"
              },
              {
                "type": "null"
              }
            ]
          },
          "lines": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/LineOut"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "With include=lines. Every line, each naming its section_id.",
            "title": "Lines"
          },
          "name": {
            "title": "Name",
            "type": "string"
          },
          "notes": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Shown to the customer on the invoice.",
            "title": "Notes"
          },
          "payment_link": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The online payment link the app already made for this invoice, if any. Read-only.",
            "title": "Payment Link"
          },
          "reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The invoice number people use, e.g. I41.",
            "title": "Reference"
          },
          "sections": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/SectionOut"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "With include=sections.",
            "title": "Sections"
          },
          "status": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/DocumentStatusRef"
              },
              {
                "type": "null"
              }
            ]
          },
          "tax_rate": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Percent, e.g. \"8.25\".",
            "title": "Tax Rate"
          },
          "terms": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Terms"
          },
          "total": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Lines plus tax, a decimal string.",
            "title": "Total"
          },
          "updated_at": {
            "format": "date-time",
            "title": "Updated At",
            "type": "string"
          }
        },
        "required": [
          "id",
          "name",
          "created_at",
          "updated_at"
        ],
        "title": "InvoiceOut",
        "type": "object"
      },
      "InvoicePage": {
        "example": {
          "data": [
            {
              "amount_due": "668.18",
              "balance": "668.18",
              "created_at": "2026-10-02T10:00:00Z",
              "currency": "USD",
              "due_date": "2026-11-01",
              "estimate": {
                "id": "4d3c2b1a-0f9e-4d8c-8b7a-6f5e4d3c2b1a",
                "name": "Whitfield kitchen"
              },
              "id": "7e6d5c4b-3a29-4180-9f7e-6d5c4b3a2918",
              "invoice_date": "2026-10-02",
              "job": {
                "id": "3f9a1c77-5e3b-4a02-9d8e-2c7b6a1f0e4d",
                "name": "Whitfield kitchen remodel"
              },
              "name": "Whitfield kitchen, deposit",
              "notes": "Deposit to schedule production.",
              "reference": "I41",
              "status": {
                "id": "5b4a3928-1706-4f5e-8d4c-3b2a19087f6e",
                "locks_editing": false,
                "name": "Open"
              },
              "tax_rate": "8.25",
              "terms": "Net 30",
              "total": "1336.35",
              "updated_at": "2026-10-02T10:00:00Z"
            }
          ],
          "has_more": false,
          "next_cursor": "eyJ2IjoiMjAyNi0xMC0wMlQxMDowMDowMCswMDowMCJ9.9b1c0e2d4f6a"
        },
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/InvoiceOut"
            },
            "title": "Data",
            "type": "array"
          },
          "has_more": {
            "default": false,
            "title": "Has More",
            "type": "boolean"
          },
          "next_cursor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Pass as `cursor` to get the next page. Null at the end.",
            "title": "Next Cursor"
          }
        },
        "title": "InvoicePage",
        "type": "object"
      },
      "InvoiceUpdateIn": {
        "description": "Only the fields you send change.",
        "example": {
          "due_date": "2026-11-15",
          "notes": "Thank you for your business."
        },
        "properties": {
          "due_date": {
            "anyOf": [
              {
                "format": "date",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Due Date"
          },
          "internal_notes": {
            "anyOf": [
              {
                "maxLength": 10000,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Internal Notes"
          },
          "invoice_date": {
            "anyOf": [
              {
                "format": "date",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Invoice Date"
          },
          "name": {
            "anyOf": [
              {
                "maxLength": 255,
                "minLength": 1,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name"
          },
          "notes": {
            "anyOf": [
              {
                "maxLength": 10000,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Notes"
          },
          "status_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "From GET /v1/meta/invoice-statuses.",
            "title": "Status Id"
          },
          "tax_rate": {
            "anyOf": [
              {
                "maximum": 100.0,
                "minimum": 0.0,
                "type": "number"
              },
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Percent, e.g. \"8.25\".",
            "title": "Tax Rate"
          },
          "terms": {
            "anyOf": [
              {
                "maxLength": 10000,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Terms"
          }
        },
        "title": "InvoiceUpdateIn",
        "type": "object"
      },
      "JobContactAddIn": {
        "description": "Either `contact_id` for somebody already in the account, or the new\nperson's details. Not both.",
        "example": {
          "email": "sam@builderco.example.com",
          "first_name": "Sam",
          "last_name": "Builder",
          "phone_number": "5125550123"
        },
        "properties": {
          "contact_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Attach this existing contact (from GET /v1/contacts) instead of creating one.",
            "title": "Contact Id"
          },
          "email": {
            "anyOf": [
              {
                "maxLength": 255,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Email"
          },
          "first_name": {
            "anyOf": [
              {
                "maxLength": 50,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "First Name"
          },
          "last_name": {
            "anyOf": [
              {
                "maxLength": 50,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Name"
          },
          "phone_number": {
            "anyOf": [
              {
                "maxLength": 15,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Up to 15 characters.",
            "title": "Phone Number"
          }
        },
        "title": "JobContactAddIn",
        "type": "object"
      },
      "JobContactIn": {
        "description": "A new contact, or an existing one by `id` (from GET /v1/contacts).",
        "properties": {
          "email": {
            "anyOf": [
              {
                "maxLength": 255,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Email"
          },
          "first_name": {
            "anyOf": [
              {
                "maxLength": 50,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "First Name"
          },
          "id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Attach an existing contact instead of creating one.",
            "title": "Id"
          },
          "last_name": {
            "anyOf": [
              {
                "maxLength": 50,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Name"
          },
          "phone_number": {
            "anyOf": [
              {
                "maxLength": 15,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Up to 15 characters, as stored.",
            "title": "Phone Number"
          }
        },
        "title": "JobContactIn",
        "type": "object"
      },
      "JobContactOut": {
        "properties": {
          "email": {
            "default": "",
            "title": "Email",
            "type": "string"
          },
          "first_name": {
            "default": "",
            "title": "First Name",
            "type": "string"
          },
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "last_name": {
            "default": "",
            "title": "Last Name",
            "type": "string"
          },
          "phone_number": {
            "default": "",
            "title": "Phone Number",
            "type": "string"
          }
        },
        "required": [
          "id"
        ],
        "title": "JobContactOut",
        "type": "object"
      },
      "JobCreateIn": {
        "example": {
          "address": {
            "city": "Austin",
            "line1": "1200 Oak Street",
            "postal_code": "78701",
            "state": "TX"
          },
          "contacts": [
            {
              "email": "dana.whitfield@example.com",
              "first_name": "Dana",
              "last_name": "Whitfield"
            }
          ],
          "custom_field_values": [
            {
              "field_id": "c0ffee00-1234-4abc-9def-0123456789ab",
              "value": "Referral"
            }
          ],
          "name": "Whitfield kitchen remodel",
          "project_manager_id": "e1d2c3b4-a596-4877-8695-a4b3c2d1e0f9",
          "stage": "opportunity"
        },
        "properties": {
          "address": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/AddressIn"
              },
              {
                "type": "null"
              }
            ]
          },
          "contacts": {
            "items": {
              "$ref": "#/components/schemas/JobContactIn"
            },
            "title": "Contacts",
            "type": "array"
          },
          "custom_field_values": {
            "items": {
              "$ref": "#/components/schemas/JobCustomFieldIn"
            },
            "title": "Custom Field Values",
            "type": "array"
          },
          "expected_end": {
            "anyOf": [
              {
                "format": "date",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Expected End"
          },
          "expected_start": {
            "anyOf": [
              {
                "format": "date",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Expected Start"
          },
          "name": {
            "maxLength": 255,
            "minLength": 1,
            "title": "Name",
            "type": "string"
          },
          "project_manager_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "A user with is_project_manager, from GET /v1/meta/users.",
            "title": "Project Manager Id"
          },
          "stage": {
            "default": "opportunity",
            "description": "Where it enters the pipeline. Defaults to opportunity.",
            "enum": [
              "lead",
              "opportunity",
              "job"
            ],
            "title": "Stage",
            "type": "string"
          },
          "timeline_template_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Timeline Template Id"
          }
        },
        "required": [
          "name"
        ],
        "title": "JobCreateIn",
        "type": "object"
      },
      "JobCustomFieldIn": {
        "properties": {
          "field_id": {
            "description": "From GET /v1/meta/custom-fields.",
            "format": "uuid",
            "title": "Field Id",
            "type": "string"
          },
          "value": {
            "maxLength": 255,
            "title": "Value",
            "type": "string"
          }
        },
        "required": [
          "field_id",
          "value"
        ],
        "title": "JobCustomFieldIn",
        "type": "object"
      },
      "JobLostIn": {
        "example": {
          "reason": "Went with another shop"
        },
        "properties": {
          "reason": {
            "anyOf": [
              {
                "maxLength": 255,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Reason"
          }
        },
        "title": "JobLostIn",
        "type": "object"
      },
      "JobOut": {
        "example": {
          "address": {
            "city": "Austin",
            "line1": "1200 Oak Street",
            "postal_code": "78701",
            "state": "TX"
          },
          "contacts": [
            {
              "email": "dana.whitfield@example.com",
              "first_name": "Dana",
              "id": "b2d4e6f8-1a3c-5e7b-9d0f-2a4c6e8b0d1f",
              "last_name": "Whitfield",
              "phone_number": "5125550147"
            }
          ],
          "created_at": "2026-09-10T14:22:05.412Z",
          "currency": "USD",
          "custom_fields": [
            {
              "field_id": "c0ffee00-1234-4abc-9def-0123456789ab",
              "name": "Lead source",
              "value": "Referral"
            }
          ],
          "expected_end": "2026-11-20",
          "expected_start": "2026-10-12",
          "id": "3f9a1c77-5e3b-4a02-9d8e-2c7b6a1f0e4d",
          "name": "Whitfield kitchen remodel",
          "project_manager": {
            "id": "e1d2c3b4-a596-4877-8695-a4b3c2d1e0f9",
            "name": "Mia Lead"
          },
          "reference": "J1042",
          "stage": "job",
          "status": {
            "entered_at": "2026-10-01T15:04:00Z",
            "id": "7a1e2f30-9c4d-4b5e-8f60-1a2b3c4d5e6f",
            "name": "Production",
            "phase": {
              "id": "8b2f3a41-0d5e-4c6f-9a71-2b3c4d5e6f70",
              "name": "Cutting"
            }
          },
          "updated_at": "2026-10-05T09:12:44.001Z",
          "value": "48250.00"
        },
        "properties": {
          "address": {
            "$ref": "#/components/schemas/AddressOut"
          },
          "contacts": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/JobContactOut"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Present on a single job, or with include=contacts.",
            "title": "Contacts"
          },
          "created_at": {
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "currency": {
            "default": "USD",
            "title": "Currency",
            "type": "string"
          },
          "custom_fields": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/CustomFieldValueOut"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Present on a single job, or with include=custom_fields.",
            "title": "Custom Fields"
          },
          "expected_end": {
            "anyOf": [
              {
                "format": "date",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Expected End"
          },
          "expected_start": {
            "anyOf": [
              {
                "format": "date",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Expected Start"
          },
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "lost_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Lost At"
          },
          "lost_reason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Lost Reason"
          },
          "name": {
            "title": "Name",
            "type": "string"
          },
          "project_manager": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Ref"
              },
              {
                "type": "null"
              }
            ]
          },
          "reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The job number people use, e.g. J1042.",
            "title": "Reference"
          },
          "stage": {
            "enum": [
              "lead",
              "opportunity",
              "job"
            ],
            "title": "Stage",
            "type": "string"
          },
          "status": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobStatusRef"
              },
              {
                "type": "null"
              }
            ]
          },
          "updated_at": {
            "format": "date-time",
            "title": "Updated At",
            "type": "string"
          },
          "value": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The primary estimate's subtotal, a decimal string. Null when the acting user cannot see costs or there is no estimate.",
            "title": "Value"
          }
        },
        "required": [
          "id",
          "name",
          "stage",
          "address",
          "created_at",
          "updated_at"
        ],
        "title": "JobOut",
        "type": "object"
      },
      "JobPage": {
        "example": {
          "data": [
            {
              "address": {
                "city": "Austin",
                "line1": "1200 Oak Street",
                "postal_code": "78701",
                "state": "TX"
              },
              "created_at": "2026-09-10T14:22:05.412Z",
              "currency": "USD",
              "expected_end": "2026-11-20",
              "expected_start": "2026-10-12",
              "id": "3f9a1c77-5e3b-4a02-9d8e-2c7b6a1f0e4d",
              "name": "Whitfield kitchen remodel",
              "project_manager": {
                "id": "e1d2c3b4-a596-4877-8695-a4b3c2d1e0f9",
                "name": "Mia Lead"
              },
              "reference": "J1042",
              "stage": "job",
              "status": {
                "entered_at": "2026-10-01T15:04:00Z",
                "id": "7a1e2f30-9c4d-4b5e-8f60-1a2b3c4d5e6f",
                "name": "Production",
                "phase": {
                  "id": "8b2f3a41-0d5e-4c6f-9a71-2b3c4d5e6f70",
                  "name": "Cutting"
                }
              },
              "updated_at": "2026-10-05T09:12:44.001Z",
              "value": "48250.00"
            }
          ],
          "has_more": true,
          "next_cursor": "eyJ2IjoiMjAyNi0wOS0xMFQxNDoyMjowNS40MTIrMDA6MDAifQ.4c1e0a9b7d2f"
        },
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/JobOut"
            },
            "title": "Data",
            "type": "array"
          },
          "has_more": {
            "default": false,
            "title": "Has More",
            "type": "boolean"
          },
          "next_cursor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Pass as `cursor` to get the next page. Null at the end.",
            "title": "Next Cursor"
          }
        },
        "title": "JobPage",
        "type": "object"
      },
      "JobRef": {
        "description": "A job this contact is on.",
        "example": {
          "id": "3f9a1c77-5e3b-4a02-9d8e-2c7b6a1f0e4d",
          "name": "Whitfield kitchen remodel",
          "reference": "J1042"
        },
        "properties": {
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name"
          },
          "reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The job number people use, e.g. J1042.",
            "title": "Reference"
          }
        },
        "required": [
          "id"
        ],
        "title": "JobRef",
        "type": "object"
      },
      "JobRefOut": {
        "properties": {
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name"
          },
          "reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Reference"
          }
        },
        "required": [
          "id"
        ],
        "title": "JobRefOut",
        "type": "object"
      },
      "JobStatusIn": {
        "example": {
          "status_id": "7a1e2f30-9c4d-4b5e-8f60-1a2b3c4d5e6f"
        },
        "properties": {
          "status_id": {
            "description": "A main status or a phase, from GET /v1/meta/job-statuses.",
            "format": "uuid",
            "title": "Status Id",
            "type": "string"
          }
        },
        "required": [
          "status_id"
        ],
        "title": "JobStatusIn",
        "type": "object"
      },
      "JobStatusOut": {
        "description": "A pipeline status. Main statuses have no `parent`; a phase sits under one.",
        "example": {
          "color": "#1a661a",
          "id": "7a1e2f30-9c4d-4b5e-8f60-1a2b3c4d5e6f",
          "is_default": false,
          "name": "Production",
          "order": 4,
          "stage": "job"
        },
        "properties": {
          "color": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Color"
          },
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "is_default": {
            "default": false,
            "title": "Is Default",
            "type": "boolean"
          },
          "name": {
            "title": "Name",
            "type": "string"
          },
          "order": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Order"
          },
          "parent": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Ref"
              },
              {
                "type": "null"
              }
            ],
            "description": "The main status this phase sits under."
          },
          "stage": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Which stage the status belongs to: lead, opportunity or job.",
            "title": "Stage"
          }
        },
        "required": [
          "id",
          "name"
        ],
        "title": "JobStatusOut",
        "type": "object"
      },
      "JobStatusRef": {
        "properties": {
          "entered_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Entered At"
          },
          "id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The main status. Null for an open opportunity.",
            "title": "Id"
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name"
          },
          "phase": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Ref"
              },
              {
                "type": "null"
              }
            ],
            "description": "The phase under the main status, if one is set."
          }
        },
        "title": "JobStatusRef",
        "type": "object"
      },
      "JobUpdateIn": {
        "description": "Only the fields you send change. The stage changes through its own\nactions (convert-to-project, move-to-lost), never here.",
        "example": {
          "address": {
            "line1": "1210 Oak Street"
          },
          "name": "Whitfield kitchen and laundry",
          "project_manager_id": "e1d2c3b4-a596-4877-8695-a4b3c2d1e0f9"
        },
        "properties": {
          "address": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/AddressIn"
              },
              {
                "type": "null"
              }
            ]
          },
          "expected_end": {
            "anyOf": [
              {
                "format": "date",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Expected End"
          },
          "expected_start": {
            "anyOf": [
              {
                "format": "date",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Expected Start"
          },
          "name": {
            "anyOf": [
              {
                "maxLength": 255,
                "minLength": 1,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name"
          },
          "project_manager_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Project Manager Id"
          }
        },
        "title": "JobUpdateIn",
        "type": "object"
      },
      "LeadCreate": {
        "description": "One incoming lead.\n\n`job_name` is the only required field. That is deliberate: a lead is the\nstart of a conversation, not a complete record, and an integration that can\nonly capture a name and a phone number should still be able to deliver them.",
        "example": {
          "address_1": "1420 Cedar Ridge Rd",
          "city": "Austin",
          "contact": {
            "email": "dana.whitfield@example.com",
            "first_name": "Dana",
            "last_name": "Whitfield",
            "phone_number": "(512) 555-0147"
          },
          "custom_field_values": [
            {
              "field_id": "9e2b7c41-4c1f-4e2a-9f6c-8b1d2e3f4a5b",
              "value": "Referral"
            }
          ],
          "form": {
            "schema_id": "7c1e9d22-8b4a-4f31-b6d5-0e9a3c5f7b2d",
            "sections": [
              {
                "name": "Kitchen",
                "values": {
                  "cabinet_style": "Shaker"
                }
              }
            ],
            "values": {
              "budget_range": "25-50k"
            }
          },
          "job_name": "Whitfield kitchen remodel",
          "notes": "Looking to replace kitchen cabinets. Budget around 30k, hoping to start in the spring.",
          "postal_code": "78704",
          "state": "TX"
        },
        "properties": {
          "address_1": {
            "anyOf": [
              {
                "maxLength": 255,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Street address.",
            "title": "Address 1"
          },
          "address_2": {
            "anyOf": [
              {
                "maxLength": 255,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Unit, suite, floor.",
            "title": "Address 2"
          },
          "city": {
            "anyOf": [
              {
                "maxLength": 255,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "City"
          },
          "contact": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ContactIn"
              },
              {
                "type": "null"
              }
            ],
            "description": "The person who enquired. Strongly recommended."
          },
          "custom_field_values": {
            "description": "Values for the account's own job fields. See GET /v1/custom-fields.",
            "items": {
              "$ref": "#/components/schemas/CustomFieldValueIn"
            },
            "title": "Custom Field Values",
            "type": "array"
          },
          "form": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/FormIn"
              },
              {
                "type": "null"
              }
            ],
            "description": "Job form data to attach. See GET /v1/job-forms."
          },
          "job_name": {
            "description": "What this job is called in the account's pipeline. Build it from what the form captured - \"Whitfield kitchen remodel\" reads better in a list than \"Website enquiry\".",
            "maxLength": 255,
            "minLength": 1,
            "title": "Job Name",
            "type": "string"
          },
          "notes": {
            "anyOf": [
              {
                "maxLength": 10000,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Free text from the enquiry - the \"tell us about your project\" box. Posted as the first message on the job so the office reads it in context instead of hunting for it.",
            "title": "Notes"
          },
          "postal_code": {
            "anyOf": [
              {
                "maxLength": 7,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Postal or ZIP code. Seven characters maximum.",
            "title": "Postal Code"
          },
          "state": {
            "anyOf": [
              {
                "maxLength": 255,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "State, province or region.",
            "title": "State"
          }
        },
        "required": [
          "job_name"
        ],
        "title": "LeadCreate",
        "type": "object"
      },
      "LeadCreated": {
        "description": "What we made. Store `id` if you want to reference the lead later.",
        "example": {
          "contact_id": "b2d4e6f8-1a3c-5e7b-9d0f-2a4c6e8b0d1f",
          "created_at": "2026-09-10T14:22:05.412000+00:00",
          "duplicate": false,
          "id": "3f9a1c77-5e3b-4a02-9d8e-2c7b6a1f0e4d",
          "job_name": "Whitfield kitchen remodel",
          "reference": "J1042",
          "stage": "lead",
          "status": "Lead",
          "warnings": []
        },
        "properties": {
          "contact_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The contact that was created, if any.",
            "title": "Contact Id"
          },
          "created_at": {
            "description": "When it was created (UTC).",
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "duplicate": {
            "default": false,
            "description": "True when this response is a replay of an earlier identical call, matched on your `Idempotency-Key`. No second lead was created.",
            "title": "Duplicate",
            "type": "boolean"
          },
          "id": {
            "description": "The lead's permanent id.",
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "job_name": {
            "description": "The name as stored.",
            "title": "Job Name",
            "type": "string"
          },
          "reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The human-facing job number the account sees, e.g. \"J1042\". Use this when a person has to find the lead, not the id.",
            "title": "Reference"
          },
          "stage": {
            "default": "lead",
            "description": "Where this sits in the pipeline. Always \"lead\" from this endpoint - the account moves it on from there.",
            "title": "Stage",
            "type": "string"
          },
          "status": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The status the lead landed in.",
            "title": "Status"
          },
          "warnings": {
            "description": "Parts of the request that were accepted but could not be applied - an unknown field key, a field that has been disabled. The lead was still created. Worth logging: this is how a form that has drifted from the account's setup tells you so.",
            "items": {
              "type": "string"
            },
            "title": "Warnings",
            "type": "array"
          }
        },
        "required": [
          "id",
          "job_name",
          "created_at"
        ],
        "title": "LeadCreated",
        "type": "object"
      },
      "LineCreateIn": {
        "description": "A line in a section. Send `product_id` to price from the catalog\n(leave `unit_price` out and the catalog's price applies), or a name and a\n`unit_price` for a free-text line.",
        "example": {
          "description": "Maple, shaker door",
          "name": "Base cabinet, 36 inch",
          "quantity": "3",
          "taxable": true,
          "unit_price": "411.50"
        },
        "properties": {
          "description": {
            "anyOf": [
              {
                "maxLength": 10000,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description"
          },
          "name": {
            "maxLength": 255,
            "minLength": 1,
            "title": "Name",
            "type": "string"
          },
          "product_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "From GET /v1/products.",
            "title": "Product Id"
          },
          "quantity": {
            "anyOf": [
              {
                "exclusiveMinimum": 0.0,
                "type": "number"
              },
              {
                "type": "string"
              }
            ],
            "title": "Quantity"
          },
          "taxable": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "Defaults to the product's setting, or false for a free-text line.",
            "title": "Taxable"
          },
          "unit_cost": {
            "anyOf": [
              {
                "minimum": 0.0,
                "type": "number"
              },
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Unit Cost"
          },
          "unit_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "From GET /v1/meta/units. Defaults to the product's unit, or Each for a free-text line.",
            "title": "Unit Id"
          },
          "unit_price": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Required on a free-text line. On a product line it overrides the catalog's price.",
            "title": "Unit Price"
          }
        },
        "required": [
          "name",
          "quantity"
        ],
        "title": "LineCreateIn",
        "type": "object"
      },
      "LineOut": {
        "example": {
          "created_at": "2026-10-01T15:06:12Z",
          "currency": "USD",
          "description": "Maple, shaker door",
          "estimate_id": "4d3c2b1a-0f9e-4d8c-8b7a-6f5e4d3c2b1a",
          "id": "1f2e3d4c-5b6a-4798-8a7b-6c5d4e3f2a1b",
          "is_discount": false,
          "name": "Base cabinet, 36 inch",
          "order": 1,
          "quantity": "3",
          "section_id": "9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
          "taxable": true,
          "total": "1234.50",
          "unit": {
            "id": "2b3c4d5e-6f70-4182-9a3b-4c5d6e7f8091",
            "name": "Each"
          },
          "unit_cost": "240.00",
          "unit_price": "411.50",
          "updated_at": "2026-10-01T15:06:12Z"
        },
        "properties": {
          "created_at": {
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "currency": {
            "default": "USD",
            "title": "Currency",
            "type": "string"
          },
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description"
          },
          "estimate_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Estimate Id"
          },
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "invoice_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Invoice Id"
          },
          "is_discount": {
            "default": false,
            "title": "Is Discount",
            "type": "boolean"
          },
          "name": {
            "title": "Name",
            "type": "string"
          },
          "order": {
            "title": "Order",
            "type": "integer"
          },
          "parent_line_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Set on the parts of an assembly. Totals count top-level lines only, so do not add these up again.",
            "title": "Parent Line Id"
          },
          "product_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Product Id"
          },
          "quantity": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "A decimal string, up to 3 decimal places.",
            "title": "Quantity"
          },
          "section_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Section Id"
          },
          "taxable": {
            "default": false,
            "title": "Taxable",
            "type": "boolean"
          },
          "total": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "quantity x unit_price, to the cent. Null when costs are hidden.",
            "title": "Total"
          },
          "unit": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Ref"
              },
              {
                "type": "null"
              }
            ]
          },
          "unit_cost": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "What the line costs the shop per unit. Null when costs are hidden or unknown.",
            "title": "Unit Cost"
          },
          "unit_price": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "A decimal string, 2 to 4 decimal places. Null when costs are hidden.",
            "title": "Unit Price"
          },
          "updated_at": {
            "format": "date-time",
            "title": "Updated At",
            "type": "string"
          }
        },
        "required": [
          "id",
          "name",
          "order",
          "created_at",
          "updated_at"
        ],
        "title": "LineOut",
        "type": "object"
      },
      "LineUpdateIn": {
        "description": "Only the fields you send change.",
        "example": {
          "quantity": "2.5",
          "unit_price": "425.00"
        },
        "properties": {
          "description": {
            "anyOf": [
              {
                "maxLength": 10000,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description"
          },
          "name": {
            "anyOf": [
              {
                "maxLength": 255,
                "minLength": 1,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name"
          },
          "quantity": {
            "anyOf": [
              {
                "exclusiveMinimum": 0.0,
                "type": "number"
              },
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Quantity"
          },
          "taxable": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Taxable"
          },
          "unit_cost": {
            "anyOf": [
              {
                "minimum": 0.0,
                "type": "number"
              },
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Unit Cost"
          },
          "unit_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Unit Id"
          },
          "unit_price": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Unit Price"
          }
        },
        "title": "LineUpdateIn",
        "type": "object"
      },
      "MaterialOut": {
        "example": {
          "attributes_text": "3/4, White",
          "created_at": "2026-08-14T10:00:00Z",
          "id": "4c5d6e7f-8091-4a2b-9c3d-4e5f60718293",
          "is_active": true,
          "name": "3/4 white melamine",
          "stock_items": [
            {
              "created_at": "2026-08-14T10:00:00Z",
              "currency": "USD",
              "id": "5d6e7f80-91a2-4b3c-8d4e-5f60718293a4",
              "is_active": true,
              "is_default": true,
              "lot_tracked": false,
              "manufacturer_sku": "WM-34-4997",
              "material_id": "4c5d6e7f-8091-4a2b-9c3d-4e5f60718293",
              "name": "49 x 97 sheet",
              "on_hand": 23.0,
              "preferred_vendor_id": "2a3b4c5d-6e7f-4809-91a2-b3c4d5e6f708",
              "reorder_point": 10.0,
              "reorder_qty": 40.0,
              "sku": "MEL-4997",
              "standard_cost": "42.50",
              "unit": "sheet",
              "updated_at": "2026-09-30T16:20:00Z",
              "values": [
                {
                  "key": "size",
                  "label": "Size",
                  "text": "49 x 97"
                }
              ]
            }
          ],
          "type": {
            "id": "3b4c5d6e-7f80-4912-a3b4-c5d6e7f80912",
            "name": "Sheet goods"
          },
          "updated_at": "2026-09-30T16:20:00Z",
          "values": [
            {
              "key": "thickness",
              "label": "Thickness",
              "text": "3/4"
            },
            {
              "key": "colour",
              "label": "Colour",
              "text": "White"
            }
          ]
        },
        "properties": {
          "attributes_text": {
            "default": "",
            "title": "Attributes Text",
            "type": "string"
          },
          "created_at": {
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description"
          },
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "is_active": {
            "default": true,
            "title": "Is Active",
            "type": "boolean"
          },
          "name": {
            "title": "Name",
            "type": "string"
          },
          "stock_items": {
            "items": {
              "$ref": "#/components/schemas/StockItemOut"
            },
            "title": "Stock Items",
            "type": "array"
          },
          "type": {
            "$ref": "#/components/schemas/Ref",
            "description": "From GET /v1/meta/material-types."
          },
          "updated_at": {
            "format": "date-time",
            "title": "Updated At",
            "type": "string"
          },
          "values": {
            "items": {
              "$ref": "#/components/schemas/AttributeValueOut"
            },
            "title": "Values",
            "type": "array"
          }
        },
        "required": [
          "id",
          "name",
          "type",
          "created_at",
          "updated_at"
        ],
        "title": "MaterialOut",
        "type": "object"
      },
      "MaterialPage": {
        "example": {
          "data": [
            {
              "attributes_text": "3/4, White",
              "created_at": "2026-08-14T10:00:00Z",
              "id": "4c5d6e7f-8091-4a2b-9c3d-4e5f60718293",
              "is_active": true,
              "name": "3/4 white melamine",
              "stock_items": [
                {
                  "created_at": "2026-08-14T10:00:00Z",
                  "currency": "USD",
                  "id": "5d6e7f80-91a2-4b3c-8d4e-5f60718293a4",
                  "is_active": true,
                  "is_default": true,
                  "lot_tracked": false,
                  "manufacturer_sku": "WM-34-4997",
                  "material_id": "4c5d6e7f-8091-4a2b-9c3d-4e5f60718293",
                  "name": "49 x 97 sheet",
                  "on_hand": 23.0,
                  "preferred_vendor_id": "2a3b4c5d-6e7f-4809-91a2-b3c4d5e6f708",
                  "reorder_point": 10.0,
                  "reorder_qty": 40.0,
                  "sku": "MEL-4997",
                  "standard_cost": "42.50",
                  "unit": "sheet",
                  "updated_at": "2026-09-30T16:20:00Z",
                  "values": [
                    {
                      "key": "size",
                      "label": "Size",
                      "text": "49 x 97"
                    }
                  ]
                }
              ],
              "type": {
                "id": "3b4c5d6e-7f80-4912-a3b4-c5d6e7f80912",
                "name": "Sheet goods"
              },
              "updated_at": "2026-09-30T16:20:00Z",
              "values": [
                {
                  "key": "thickness",
                  "label": "Thickness",
                  "text": "3/4"
                },
                {
                  "key": "colour",
                  "label": "Colour",
                  "text": "White"
                }
              ]
            }
          ],
          "has_more": true,
          "next_cursor": "eyJ2IjoiMy80IHdoaXRlIG1lbGFtaW5lIn0.9b7d2f4c1e0a"
        },
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/MaterialOut"
            },
            "title": "Data",
            "type": "array"
          },
          "has_more": {
            "default": false,
            "title": "Has More",
            "type": "boolean"
          },
          "next_cursor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Pass as `cursor` to get the next page. Null at the end.",
            "title": "Next Cursor"
          }
        },
        "title": "MaterialPage",
        "type": "object"
      },
      "MaterialTypeOut": {
        "example": {
          "id": "b2c3d4e5-f6a7-4890-9bcd-ef0123456789",
          "key": "sheet",
          "name": "Sheet goods",
          "stock_unit": "sheet"
        },
        "properties": {
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "key": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Key"
          },
          "name": {
            "title": "Name",
            "type": "string"
          },
          "stock_unit": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Stock Unit"
          }
        },
        "required": [
          "id",
          "name"
        ],
        "title": "MaterialTypeOut",
        "type": "object"
      },
      "NoteCreateIn": {
        "example": {
          "content": "Customer called: they want to see the door samples on Friday."
        },
        "properties": {
          "content": {
            "description": "Plain text. Up to 10,000 characters.",
            "maxLength": 10000,
            "minLength": 1,
            "title": "Content",
            "type": "string"
          }
        },
        "required": [
          "content"
        ],
        "title": "NoteCreateIn",
        "type": "object"
      },
      "NoteOut": {
        "example": {
          "author": {
            "id": "e1d2c3b4-a596-4877-8695-a4b3c2d1e0f9",
            "name": "Mia Lead"
          },
          "content": "Deposit received. @[0c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f:Rob Owner] can you order the hinges?",
          "created_at": "2026-10-05T09:12:44.001Z",
          "id": "6d0e5f4a-3b2c-4d1e-8f9a-0b1c2d3e4f5a",
          "is_edited": false,
          "is_system": false,
          "job_id": "3f9a1c77-5e3b-4a02-9d8e-2c7b6a1f0e4d",
          "text": "Deposit received. @Rob Owner can you order the hinges?",
          "updated_at": "2026-10-05T09:12:44.001Z"
        },
        "properties": {
          "author": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/AuthorRef"
              },
              {
                "type": "null"
              }
            ],
            "description": "Null when the user who wrote it has since been removed."
          },
          "content": {
            "description": "The note as stored, with mentions in their @[user_id:Name] form.",
            "title": "Content",
            "type": "string"
          },
          "created_at": {
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "is_edited": {
            "default": false,
            "description": "True when the author changed it after posting, in the app.",
            "title": "Is Edited",
            "type": "boolean"
          },
          "is_system": {
            "default": false,
            "description": "True for notes the product wrote itself, such as a lead's submitted message.",
            "title": "Is System",
            "type": "boolean"
          },
          "job_id": {
            "format": "uuid",
            "title": "Job Id",
            "type": "string"
          },
          "text": {
            "description": "The note as people read it, with mentions shown as @Name.",
            "title": "Text",
            "type": "string"
          },
          "updated_at": {
            "format": "date-time",
            "title": "Updated At",
            "type": "string"
          }
        },
        "required": [
          "id",
          "job_id",
          "content",
          "text",
          "created_at",
          "updated_at"
        ],
        "title": "NoteOut",
        "type": "object"
      },
      "NotePage": {
        "example": {
          "data": [
            {
              "author": {
                "id": "e1d2c3b4-a596-4877-8695-a4b3c2d1e0f9",
                "name": "Mia Lead"
              },
              "content": "Deposit received. @[0c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f:Rob Owner] can you order the hinges?",
              "created_at": "2026-10-05T09:12:44.001Z",
              "id": "6d0e5f4a-3b2c-4d1e-8f9a-0b1c2d3e4f5a",
              "is_edited": false,
              "is_system": false,
              "job_id": "3f9a1c77-5e3b-4a02-9d8e-2c7b6a1f0e4d",
              "text": "Deposit received. @Rob Owner can you order the hinges?",
              "updated_at": "2026-10-05T09:12:44.001Z"
            }
          ],
          "has_more": true,
          "next_cursor": "eyJ2IjoiMjAyNi0xMC0wNVQwOToxMjo0NC4wMDErMDA6MDAifQ.9b8a7c6d5e4f"
        },
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/NoteOut"
            },
            "title": "Data",
            "type": "array"
          },
          "has_more": {
            "default": false,
            "title": "Has More",
            "type": "boolean"
          },
          "next_cursor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Pass as `cursor` to get the next page. Null at the end.",
            "title": "Next Cursor"
          }
        },
        "title": "NotePage",
        "type": "object"
      },
      "POLineIn": {
        "example": {
          "item_name": "3/4 white melamine, 49 x 97 sheet",
          "quantity": 12,
          "sku": "MEL-4997",
          "stock_item_id": "5d6e7f80-91a2-4b3c-8d4e-5f60718293a4",
          "unit_cost": 42.5,
          "unit_name": "sheet"
        },
        "properties": {
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description"
          },
          "item_name": {
            "maxLength": 255,
            "minLength": 1,
            "title": "Item Name",
            "type": "string"
          },
          "job_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Only when this line is for a different job than the order.",
            "title": "Job Id"
          },
          "quantity": {
            "default": 1.0,
            "exclusiveMinimum": 0.0,
            "title": "Quantity",
            "type": "number"
          },
          "sku": {
            "anyOf": [
              {
                "maxLength": 100,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Sku"
          },
          "stock_item_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "From GET /v1/materials.",
            "title": "Stock Item Id"
          },
          "unit_cost": {
            "default": 0.0,
            "minimum": 0.0,
            "title": "Unit Cost",
            "type": "number"
          },
          "unit_name": {
            "anyOf": [
              {
                "maxLength": 50,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Unit Name"
          }
        },
        "required": [
          "item_name"
        ],
        "title": "POLineIn",
        "type": "object"
      },
      "POLineOut": {
        "example": {
          "created_at": "2026-10-02T11:00:00Z",
          "currency": "USD",
          "extended_cost": "510.00",
          "id": "91a2b3c4-d5e6-4f70-8192-a3b4c5d6e7f8",
          "item_name": "3/4 white melamine, 49 x 97 sheet",
          "quantity": 12.0,
          "received_quantity": 8.0,
          "sku": "MEL-4997",
          "sort_order": 0,
          "stock_item_id": "5d6e7f80-91a2-4b3c-8d4e-5f60718293a4",
          "unit_cost": "42.50",
          "unit_name": "sheet",
          "updated_at": "2026-10-02T11:00:00Z"
        },
        "properties": {
          "actual_unit_cost": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "What the supplier billed, when it differed from the order.",
            "title": "Actual Unit Cost"
          },
          "created_at": {
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "currency": {
            "default": "USD",
            "title": "Currency",
            "type": "string"
          },
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description"
          },
          "extended_cost": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Extended Cost"
          },
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "item_name": {
            "title": "Item Name",
            "type": "string"
          },
          "job_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Set when this line is for a different job than the order.",
            "title": "Job Id"
          },
          "quantity": {
            "title": "Quantity",
            "type": "number"
          },
          "received_quantity": {
            "default": 0.0,
            "description": "Everything received against this line so far.",
            "title": "Received Quantity",
            "type": "number"
          },
          "sku": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Sku"
          },
          "sort_order": {
            "default": 0,
            "title": "Sort Order",
            "type": "integer"
          },
          "stock_item_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Stock Item Id"
          },
          "unit_cost": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Decimal string, up to four places.",
            "title": "Unit Cost"
          },
          "unit_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Unit Name"
          },
          "updated_at": {
            "format": "date-time",
            "title": "Updated At",
            "type": "string"
          }
        },
        "required": [
          "id",
          "item_name",
          "quantity",
          "created_at",
          "updated_at"
        ],
        "title": "POLineOut",
        "type": "object"
      },
      "POLineUpdateIn": {
        "description": "Only the fields you send change.",
        "example": {
          "quantity": 14,
          "unit_cost": 41.75
        },
        "properties": {
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description"
          },
          "item_name": {
            "anyOf": [
              {
                "maxLength": 255,
                "minLength": 1,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Item Name"
          },
          "job_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Job Id"
          },
          "quantity": {
            "anyOf": [
              {
                "exclusiveMinimum": 0.0,
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Quantity"
          },
          "sku": {
            "anyOf": [
              {
                "maxLength": 100,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Sku"
          },
          "stock_item_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Stock Item Id"
          },
          "unit_cost": {
            "anyOf": [
              {
                "minimum": 0.0,
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Unit Cost"
          },
          "unit_name": {
            "anyOf": [
              {
                "maxLength": 50,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Unit Name"
          }
        },
        "title": "POLineUpdateIn",
        "type": "object"
      },
      "PaymentApplicationOut": {
        "properties": {
          "amount": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Amount"
          },
          "invoice": {
            "$ref": "#/components/schemas/Ref"
          }
        },
        "required": [
          "invoice"
        ],
        "title": "PaymentApplicationOut",
        "type": "object"
      },
      "PaymentOut": {
        "example": {
          "amount": "668.18",
          "applications": [
            {
              "amount": "668.18",
              "invoice": {
                "id": "7e6d5c4b-3a29-4180-9f7e-6d5c4b3a2918",
                "name": "Whitfield kitchen, deposit"
              }
            }
          ],
          "created_at": "2026-10-03T16:20:00Z",
          "currency": "USD",
          "id": "0a1b2c3d-4e5f-4607-8a9b-0c1d2e3f4a5b",
          "invoice": {
            "id": "7e6d5c4b-3a29-4180-9f7e-6d5c4b3a2918",
            "name": "Whitfield kitchen, deposit"
          },
          "job": {
            "id": "3f9a1c77-5e3b-4a02-9d8e-2c7b6a1f0e4d",
            "name": "Whitfield kitchen remodel"
          },
          "method": "CHECK",
          "name": "Deposit cheque",
          "payment_date": "2026-10-03",
          "payment_reference": "Cheque 1042",
          "reference": "P12",
          "status": {
            "id": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
            "name": "Received"
          },
          "type": "RECORD",
          "updated_at": "2026-10-03T16:20:00Z"
        },
        "properties": {
          "amount": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "A decimal string. Null when the acting user cannot see costs.",
            "title": "Amount"
          },
          "applications": {
            "description": "Every invoice this payment settles and how much of each. Empty when nothing is applied.",
            "items": {
              "$ref": "#/components/schemas/PaymentApplicationOut"
            },
            "title": "Applications",
            "type": "array"
          },
          "applied_amount": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Read through one invoice (invoice_id, or /v1/invoices/{id}/payments): what this payment applies to it.",
            "title": "Applied Amount"
          },
          "created_at": {
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "currency": {
            "default": "USD",
            "title": "Currency",
            "type": "string"
          },
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "invoice": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Ref"
              },
              {
                "type": "null"
              }
            ],
            "description": "The invoice the payment was recorded against."
          },
          "job": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Ref"
              },
              {
                "type": "null"
              }
            ]
          },
          "method": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "ACH, CREDIT, CHECK, CASH or OTHER.",
            "title": "Method"
          },
          "name": {
            "title": "Name",
            "type": "string"
          },
          "notes": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Notes"
          },
          "payment_date": {
            "anyOf": [
              {
                "format": "date",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Payment Date"
          },
          "payment_reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The cheque number or transaction reference typed in with it.",
            "title": "Payment Reference"
          },
          "reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The payment number people use, e.g. P12.",
            "title": "Reference"
          },
          "status": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/PaymentStatusRef"
              },
              {
                "type": "null"
              }
            ]
          },
          "type": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "How it was taken: LINK (online), IN_PERSON, RECORD (entered by hand), CREDIT_MEMO, REFUND.",
            "title": "Type"
          },
          "updated_at": {
            "format": "date-time",
            "title": "Updated At",
            "type": "string"
          }
        },
        "required": [
          "id",
          "name",
          "created_at",
          "updated_at"
        ],
        "title": "PaymentOut",
        "type": "object"
      },
      "PaymentPage": {
        "example": {
          "data": [
            {
              "amount": "668.18",
              "applications": [
                {
                  "amount": "668.18",
                  "invoice": {
                    "id": "7e6d5c4b-3a29-4180-9f7e-6d5c4b3a2918",
                    "name": "Whitfield kitchen, deposit"
                  }
                }
              ],
              "created_at": "2026-10-03T16:20:00Z",
              "currency": "USD",
              "id": "0a1b2c3d-4e5f-4607-8a9b-0c1d2e3f4a5b",
              "invoice": {
                "id": "7e6d5c4b-3a29-4180-9f7e-6d5c4b3a2918",
                "name": "Whitfield kitchen, deposit"
              },
              "job": {
                "id": "3f9a1c77-5e3b-4a02-9d8e-2c7b6a1f0e4d",
                "name": "Whitfield kitchen remodel"
              },
              "method": "CHECK",
              "name": "Deposit cheque",
              "payment_date": "2026-10-03",
              "payment_reference": "Cheque 1042",
              "reference": "P12",
              "status": {
                "id": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
                "name": "Received"
              },
              "type": "RECORD",
              "updated_at": "2026-10-03T16:20:00Z"
            }
          ],
          "has_more": false
        },
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/PaymentOut"
            },
            "title": "Data",
            "type": "array"
          },
          "has_more": {
            "default": false,
            "title": "Has More",
            "type": "boolean"
          },
          "next_cursor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Pass as `cursor` to get the next page. Null at the end.",
            "title": "Next Cursor"
          }
        },
        "title": "PaymentPage",
        "type": "object"
      },
      "PaymentStatusRef": {
        "properties": {
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name"
          }
        },
        "required": [
          "id"
        ],
        "title": "PaymentStatusRef",
        "type": "object"
      },
      "ProductCategoryOut": {
        "example": {
          "id": "a1b2c3d4-e5f6-4789-8abc-def012345678",
          "kind": "product",
          "name": "Base cabinets"
        },
        "properties": {
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "kind": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Kind"
          },
          "name": {
            "title": "Name",
            "type": "string"
          },
          "parent_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Parent Id"
          }
        },
        "required": [
          "id",
          "name"
        ],
        "title": "ProductCategoryOut",
        "type": "object"
      },
      "ProductCreateIn": {
        "example": {
          "category_id": "d2e3f4a5-b6c7-4d8e-9fa0-b1c2d3e4f5a6",
          "cost": 212.4,
          "name": "Base cabinet, 24 in",
          "price": 485,
          "sku": "BC24",
          "unit_id": "e3f4a5b6-c7d8-4e9f-a0b1-c2d3e4f5a6b7"
        },
        "properties": {
          "category_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "From GET /v1/meta/product-categories.",
            "title": "Category Id"
          },
          "cost": {
            "anyOf": [
              {
                "minimum": 0.0,
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Cost"
          },
          "default_vendor_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "From GET /v1/vendors.",
            "title": "Default Vendor Id"
          },
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description"
          },
          "display_name": {
            "anyOf": [
              {
                "maxLength": 255,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Display Name"
          },
          "kind": {
            "anyOf": [
              {
                "enum": [
                  "made",
                  "purchased",
                  "service"
                ],
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Leave out to follow the category. Send null on an update to go back to it.",
            "title": "Kind"
          },
          "markup_pct": {
            "anyOf": [
              {
                "minimum": 0.0,
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Markup Pct"
          },
          "name": {
            "maxLength": 255,
            "minLength": 2,
            "title": "Name",
            "type": "string"
          },
          "price": {
            "anyOf": [
              {
                "minimum": 0.0,
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Price"
          },
          "pricing_mode": {
            "anyOf": [
              {
                "enum": [
                  "manual",
                  "margin",
                  "markup"
                ],
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Left out on create, follows the kind: purchased is markup.",
            "title": "Pricing Mode"
          },
          "sku": {
            "anyOf": [
              {
                "maxLength": 64,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Unique in the account.",
            "title": "Sku"
          },
          "stock_item_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "From GET /v1/materials.",
            "title": "Stock Item Id"
          },
          "target_margin_pct": {
            "anyOf": [
              {
                "exclusiveMaximum": 100.0,
                "minimum": 0.0,
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Target Margin Pct"
          },
          "taxable": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "Left out on create, follows the kind: purchased goods are taxed.",
            "title": "Taxable"
          },
          "unit_id": {
            "description": "From GET /v1/meta/units.",
            "format": "uuid",
            "title": "Unit Id",
            "type": "string"
          },
          "waste_pct": {
            "anyOf": [
              {
                "exclusiveMaximum": 100.0,
                "minimum": 0.0,
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Waste Pct"
          }
        },
        "required": [
          "name",
          "unit_id"
        ],
        "title": "ProductCreateIn",
        "type": "object"
      },
      "ProductOut": {
        "example": {
          "category": {
            "id": "d2e3f4a5-b6c7-4d8e-9fa0-b1c2d3e4f5a6",
            "name": "Base cabinets"
          },
          "cost": "212.40",
          "created_at": "2026-05-11T09:00:00Z",
          "currency": "USD",
          "description": "Frameless, one drawer over one door.",
          "display_name": "24 in base cabinet",
          "id": "c1d2e3f4-a5b6-4c7d-8e9f-a0b1c2d3e4f5",
          "is_active": true,
          "kind": "made",
          "kind_is_own": false,
          "name": "Base cabinet, 24 in",
          "price": "485.00",
          "pricing_mode": "manual",
          "sku": "BC24",
          "taxable": false,
          "type": "standard",
          "unit": {
            "abbreviation": "ea",
            "id": "e3f4a5b6-c7d8-4e9f-a0b1-c2d3e4f5a6b7",
            "name": "Each"
          },
          "updated_at": "2026-09-22T17:40:00Z"
        },
        "properties": {
          "archived_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Archived At"
          },
          "category": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Ref"
              },
              {
                "type": "null"
              }
            ],
            "description": "From GET /v1/meta/product-categories."
          },
          "cost": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Cost per unit, decimal string. Null when not entered or hidden from this role.",
            "title": "Cost"
          },
          "created_at": {
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "currency": {
            "default": "USD",
            "title": "Currency",
            "type": "string"
          },
          "default_vendor_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Purchased goods: the supplier suggested first.",
            "title": "Default Vendor Id"
          },
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description"
          },
          "display_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "What the customer reads. Null means name.",
            "title": "Display Name"
          },
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "is_active": {
            "default": true,
            "title": "Is Active",
            "type": "boolean"
          },
          "is_percentage": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "A discount only: price is a percent.",
            "title": "Is Percentage"
          },
          "kind": {
            "default": "made",
            "description": "made, purchased or service: the product's own, else its category's.",
            "enum": [
              "made",
              "purchased",
              "service"
            ],
            "title": "Kind",
            "type": "string"
          },
          "kind_is_own": {
            "default": false,
            "description": "True when the product sets its kind; false when it follows its category.",
            "title": "Kind Is Own",
            "type": "boolean"
          },
          "markup_pct": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Markup Pct"
          },
          "name": {
            "title": "Name",
            "type": "string"
          },
          "price": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Price per unit, decimal string, up to four places.",
            "title": "Price"
          },
          "pricing_mode": {
            "default": "manual",
            "enum": [
              "manual",
              "margin",
              "markup"
            ],
            "title": "Pricing Mode",
            "type": "string"
          },
          "sku": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Sku"
          },
          "stock_item_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Purchased goods: the catalog item this product is.",
            "title": "Stock Item Id"
          },
          "target_margin_pct": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Target Margin Pct"
          },
          "taxable": {
            "default": false,
            "title": "Taxable",
            "type": "boolean"
          },
          "type": {
            "default": "standard",
            "description": "standard, or discount for a discount line.",
            "title": "Type",
            "type": "string"
          },
          "unit": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/app__api__v1__products__schema__UnitOut"
              },
              {
                "type": "null"
              }
            ]
          },
          "updated_at": {
            "format": "date-time",
            "title": "Updated At",
            "type": "string"
          },
          "waste_pct": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Waste Pct"
          }
        },
        "required": [
          "id",
          "name",
          "created_at",
          "updated_at"
        ],
        "title": "ProductOut",
        "type": "object"
      },
      "ProductPage": {
        "example": {
          "data": [
            {
              "category": {
                "id": "d2e3f4a5-b6c7-4d8e-9fa0-b1c2d3e4f5a6",
                "name": "Base cabinets"
              },
              "cost": "212.40",
              "created_at": "2026-05-11T09:00:00Z",
              "currency": "USD",
              "description": "Frameless, one drawer over one door.",
              "display_name": "24 in base cabinet",
              "id": "c1d2e3f4-a5b6-4c7d-8e9f-a0b1c2d3e4f5",
              "is_active": true,
              "kind": "made",
              "kind_is_own": false,
              "name": "Base cabinet, 24 in",
              "price": "485.00",
              "pricing_mode": "manual",
              "sku": "BC24",
              "taxable": false,
              "type": "standard",
              "unit": {
                "abbreviation": "ea",
                "id": "e3f4a5b6-c7d8-4e9f-a0b1-c2d3e4f5a6b7",
                "name": "Each"
              },
              "updated_at": "2026-09-22T17:40:00Z"
            }
          ],
          "has_more": true,
          "next_cursor": "eyJ2IjoiMjAyNi0wNS0xMVQwOTowMDowMCswMDowMCJ9.0a9b7d2f4c1e"
        },
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/ProductOut"
            },
            "title": "Data",
            "type": "array"
          },
          "has_more": {
            "default": false,
            "title": "Has More",
            "type": "boolean"
          },
          "next_cursor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Pass as `cursor` to get the next page. Null at the end.",
            "title": "Next Cursor"
          }
        },
        "title": "ProductPage",
        "type": "object"
      },
      "ProductUpdateIn": {
        "description": "Only the fields you send change. Archiving a product is done in the\napp, where it shows what still uses it.",
        "example": {
          "cost": 218.75,
          "price": 499
        },
        "properties": {
          "category_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "From GET /v1/meta/product-categories.",
            "title": "Category Id"
          },
          "cost": {
            "anyOf": [
              {
                "minimum": 0.0,
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Cost"
          },
          "default_vendor_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "From GET /v1/vendors.",
            "title": "Default Vendor Id"
          },
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description"
          },
          "display_name": {
            "anyOf": [
              {
                "maxLength": 255,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Display Name"
          },
          "kind": {
            "anyOf": [
              {
                "enum": [
                  "made",
                  "purchased",
                  "service"
                ],
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Leave out to follow the category. Send null on an update to go back to it.",
            "title": "Kind"
          },
          "markup_pct": {
            "anyOf": [
              {
                "minimum": 0.0,
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Markup Pct"
          },
          "name": {
            "anyOf": [
              {
                "maxLength": 255,
                "minLength": 2,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name"
          },
          "price": {
            "anyOf": [
              {
                "minimum": 0.0,
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Price"
          },
          "pricing_mode": {
            "anyOf": [
              {
                "enum": [
                  "manual",
                  "margin",
                  "markup"
                ],
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Left out on create, follows the kind: purchased is markup.",
            "title": "Pricing Mode"
          },
          "sku": {
            "anyOf": [
              {
                "maxLength": 64,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Unique in the account.",
            "title": "Sku"
          },
          "stock_item_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "From GET /v1/materials.",
            "title": "Stock Item Id"
          },
          "target_margin_pct": {
            "anyOf": [
              {
                "exclusiveMaximum": 100.0,
                "minimum": 0.0,
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Target Margin Pct"
          },
          "taxable": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "Left out on create, follows the kind: purchased goods are taxed.",
            "title": "Taxable"
          },
          "unit_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Unit Id"
          },
          "waste_pct": {
            "anyOf": [
              {
                "exclusiveMaximum": 100.0,
                "minimum": 0.0,
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Waste Pct"
          }
        },
        "title": "ProductUpdateIn",
        "type": "object"
      },
      "PurchaseOrderCreateIn": {
        "example": {
          "job_id": "3f9a1c77-5e3b-4a02-9d8e-2c7b6a1f0e4d",
          "kind": "job",
          "lines": [
            {
              "item_name": "3/4 white melamine, 49 x 97 sheet",
              "quantity": 12,
              "unit_cost": 42.5,
              "unit_name": "sheet"
            }
          ],
          "name": "Whitfield sheet goods",
          "status": "draft",
          "vendor_id": "2a3b4c5d-6e7f-4809-91a2-b3c4d5e6f708"
        },
        "properties": {
          "expected_delivery_date": {
            "anyOf": [
              {
                "format": "date",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Expected Delivery Date"
          },
          "job_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Job Id"
          },
          "kind": {
            "default": "job",
            "description": "job needs job_id; stock has none.",
            "enum": [
              "job",
              "stock"
            ],
            "title": "Kind",
            "type": "string"
          },
          "lines": {
            "items": {
              "$ref": "#/components/schemas/POLineIn"
            },
            "title": "Lines",
            "type": "array"
          },
          "name": {
            "maxLength": 255,
            "minLength": 1,
            "title": "Name",
            "type": "string"
          },
          "notes": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Notes"
          },
          "status": {
            "default": "draft",
            "enum": [
              "draft",
              "submitted"
            ],
            "title": "Status",
            "type": "string"
          },
          "vendor_id": {
            "description": "From GET /v1/vendors.",
            "format": "uuid",
            "title": "Vendor Id",
            "type": "string"
          }
        },
        "required": [
          "name",
          "vendor_id"
        ],
        "title": "PurchaseOrderCreateIn",
        "type": "object"
      },
      "PurchaseOrderOut": {
        "example": {
          "created_at": "2026-10-02T11:00:00Z",
          "currency": "USD",
          "expected_delivery_derived": "2026-10-07",
          "id": "8091a2b3-c4d5-4e6f-9071-8293a4b5c6d7",
          "job": {
            "id": "3f9a1c77-5e3b-4a02-9d8e-2c7b6a1f0e4d",
            "name": "Whitfield kitchen remodel",
            "reference": "J1042"
          },
          "kind": "job",
          "lines": [
            {
              "created_at": "2026-10-02T11:00:00Z",
              "currency": "USD",
              "extended_cost": "510.00",
              "id": "91a2b3c4-d5e6-4f70-8192-a3b4c5d6e7f8",
              "item_name": "3/4 white melamine, 49 x 97 sheet",
              "quantity": 12.0,
              "received_quantity": 8.0,
              "sku": "MEL-4997",
              "sort_order": 0,
              "stock_item_id": "5d6e7f80-91a2-4b3c-8d4e-5f60718293a4",
              "unit_cost": "42.50",
              "unit_name": "sheet",
              "updated_at": "2026-10-02T11:00:00Z"
            }
          ],
          "name": "Whitfield sheet goods",
          "notes": "Deliver to the back dock.",
          "reference": "PO112",
          "status": "partial",
          "submitted_at": "2026-10-02T11:05:00Z",
          "subtotal": "510.00",
          "tax_amount": "42.08",
          "tax_rate": 8.25,
          "total": "552.08",
          "updated_at": "2026-10-04T15:30:00Z",
          "vendor": {
            "id": "2a3b4c5d-6e7f-4809-91a2-b3c4d5e6f708",
            "name": "Acme Panel Supply"
          }
        },
        "properties": {
          "created_at": {
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "currency": {
            "default": "USD",
            "title": "Currency",
            "type": "string"
          },
          "expected_delivery_date": {
            "anyOf": [
              {
                "format": "date",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Expected Delivery Date"
          },
          "expected_delivery_derived": {
            "anyOf": [
              {
                "format": "date",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The typed date, else submitted plus the supplier's lead time. Null when neither is known.",
            "title": "Expected Delivery Derived"
          },
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "job": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobRefOut"
              },
              {
                "type": "null"
              }
            ]
          },
          "kind": {
            "default": "job",
            "description": "job: bought for one job. stock: bought for the shelf.",
            "enum": [
              "job",
              "stock"
            ],
            "title": "Kind",
            "type": "string"
          },
          "lines": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/POLineOut"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Present on a single purchase order.",
            "title": "Lines"
          },
          "name": {
            "title": "Name",
            "type": "string"
          },
          "notes": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Notes"
          },
          "received_date": {
            "anyOf": [
              {
                "format": "date",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Received Date"
          },
          "reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The order number, e.g. PO112.",
            "title": "Reference"
          },
          "status": {
            "enum": [
              "draft",
              "submitted",
              "partial",
              "received",
              "cancelled"
            ],
            "title": "Status",
            "type": "string"
          },
          "submitted_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Submitted At"
          },
          "subtotal": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Subtotal"
          },
          "tax_amount": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Tax Amount"
          },
          "tax_rate": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "description": "A percent, e.g. 8.25.",
            "title": "Tax Rate"
          },
          "total": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Total"
          },
          "updated_at": {
            "format": "date-time",
            "title": "Updated At",
            "type": "string"
          },
          "vendor": {
            "$ref": "#/components/schemas/Ref"
          }
        },
        "required": [
          "id",
          "name",
          "status",
          "vendor",
          "created_at",
          "updated_at"
        ],
        "title": "PurchaseOrderOut",
        "type": "object"
      },
      "PurchaseOrderPage": {
        "example": {
          "data": [
            {
              "created_at": "2026-10-02T11:00:00Z",
              "currency": "USD",
              "expected_delivery_derived": "2026-10-07",
              "id": "8091a2b3-c4d5-4e6f-9071-8293a4b5c6d7",
              "job": {
                "id": "3f9a1c77-5e3b-4a02-9d8e-2c7b6a1f0e4d",
                "name": "Whitfield kitchen remodel",
                "reference": "J1042"
              },
              "kind": "job",
              "name": "Whitfield sheet goods",
              "notes": "Deliver to the back dock.",
              "reference": "PO112",
              "status": "partial",
              "submitted_at": "2026-10-02T11:05:00Z",
              "subtotal": "510.00",
              "tax_amount": "42.08",
              "tax_rate": 8.25,
              "total": "552.08",
              "updated_at": "2026-10-04T15:30:00Z",
              "vendor": {
                "id": "2a3b4c5d-6e7f-4809-91a2-b3c4d5e6f708",
                "name": "Acme Panel Supply"
              }
            }
          ],
          "has_more": true,
          "next_cursor": "eyJ2IjoiMjAyNi0xMC0wMlQxMTowMDowMCswMDowMCJ9.7d2f4c1e0a9b"
        },
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/PurchaseOrderOut"
            },
            "title": "Data",
            "type": "array"
          },
          "has_more": {
            "default": false,
            "title": "Has More",
            "type": "boolean"
          },
          "next_cursor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Pass as `cursor` to get the next page. Null at the end.",
            "title": "Next Cursor"
          }
        },
        "title": "PurchaseOrderPage",
        "type": "object"
      },
      "PurchaseOrderRef": {
        "properties": {
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The order number, e.g. PO112.",
            "title": "Reference"
          }
        },
        "required": [
          "id"
        ],
        "title": "PurchaseOrderRef",
        "type": "object"
      },
      "PurchaseOrderUpdateIn": {
        "description": "Only the fields you send change. Status moves between draft,\nsubmitted and cancelled here; partial and received follow from\n`POST /v1/purchase-orders/{id}/receive`.",
        "example": {
          "expected_delivery_date": "2026-10-09",
          "status": "submitted"
        },
        "properties": {
          "expected_delivery_date": {
            "anyOf": [
              {
                "format": "date",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Expected Delivery Date"
          },
          "job_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Job Id"
          },
          "name": {
            "anyOf": [
              {
                "maxLength": 255,
                "minLength": 1,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name"
          },
          "notes": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Notes"
          },
          "status": {
            "anyOf": [
              {
                "enum": [
                  "draft",
                  "submitted",
                  "cancelled"
                ],
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Status"
          },
          "tax_rate": {
            "anyOf": [
              {
                "maximum": 100.0,
                "minimum": 0.0,
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "description": "A percent, e.g. 8.25.",
            "title": "Tax Rate"
          },
          "vendor_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Vendor Id"
          }
        },
        "title": "PurchaseOrderUpdateIn",
        "type": "object"
      },
      "ReceiptLineOut": {
        "properties": {
          "line_id": {
            "format": "uuid",
            "title": "Line Id",
            "type": "string"
          },
          "quantity": {
            "title": "Quantity",
            "type": "number"
          }
        },
        "required": [
          "line_id",
          "quantity"
        ],
        "title": "ReceiptLineOut",
        "type": "object"
      },
      "ReceiptOut": {
        "properties": {
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "lines": {
            "items": {
              "$ref": "#/components/schemas/ReceiptLineOut"
            },
            "title": "Lines",
            "type": "array"
          },
          "packing_slip_ref": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Packing Slip Ref"
          },
          "received_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Received At"
          }
        },
        "required": [
          "id"
        ],
        "title": "ReceiptOut",
        "type": "object"
      },
      "ReceiveIn": {
        "example": {
          "lines": [
            {
              "line_id": "91a2b3c4-d5e6-4f70-8192-a3b4c5d6e7f8",
              "quantity": 8
            }
          ],
          "packing_slip_ref": "PS-20931"
        },
        "properties": {
          "lines": {
            "items": {
              "$ref": "#/components/schemas/ReceiveLineIn"
            },
            "minItems": 1,
            "title": "Lines",
            "type": "array"
          },
          "notes": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Notes"
          },
          "packing_slip_ref": {
            "anyOf": [
              {
                "maxLength": 120,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Packing Slip Ref"
          },
          "received_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When it arrived. Defaults to now.",
            "title": "Received At"
          },
          "to_location_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Required when the account tracks inventory: the stock location the goods went to.",
            "title": "To Location Id"
          }
        },
        "required": [
          "lines"
        ],
        "title": "ReceiveIn",
        "type": "object"
      },
      "ReceiveLineIn": {
        "properties": {
          "line_id": {
            "description": "A line of this purchase order.",
            "format": "uuid",
            "title": "Line Id",
            "type": "string"
          },
          "quantity": {
            "description": "How many arrived. More than the line still owes is refused.",
            "exclusiveMinimum": 0.0,
            "title": "Quantity",
            "type": "number"
          },
          "unit_cost": {
            "anyOf": [
              {
                "minimum": 0.0,
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "description": "What it cost, when different from the line's.",
            "title": "Unit Cost"
          }
        },
        "required": [
          "line_id",
          "quantity"
        ],
        "title": "ReceiveLineIn",
        "type": "object"
      },
      "ReceiveResultOut": {
        "example": {
          "purchase_order": {
            "created_at": "2026-10-02T11:00:00Z",
            "currency": "USD",
            "expected_delivery_derived": "2026-10-07",
            "id": "8091a2b3-c4d5-4e6f-9071-8293a4b5c6d7",
            "job": {
              "id": "3f9a1c77-5e3b-4a02-9d8e-2c7b6a1f0e4d",
              "name": "Whitfield kitchen remodel",
              "reference": "J1042"
            },
            "kind": "job",
            "lines": [
              {
                "created_at": "2026-10-02T11:00:00Z",
                "currency": "USD",
                "extended_cost": "510.00",
                "id": "91a2b3c4-d5e6-4f70-8192-a3b4c5d6e7f8",
                "item_name": "3/4 white melamine, 49 x 97 sheet",
                "quantity": 12.0,
                "received_quantity": 8.0,
                "sku": "MEL-4997",
                "sort_order": 0,
                "stock_item_id": "5d6e7f80-91a2-4b3c-8d4e-5f60718293a4",
                "unit_cost": "42.50",
                "unit_name": "sheet",
                "updated_at": "2026-10-02T11:00:00Z"
              }
            ],
            "name": "Whitfield sheet goods",
            "notes": "Deliver to the back dock.",
            "reference": "PO112",
            "status": "partial",
            "submitted_at": "2026-10-02T11:05:00Z",
            "subtotal": "510.00",
            "tax_amount": "42.08",
            "tax_rate": 8.25,
            "total": "552.08",
            "updated_at": "2026-10-04T15:30:00Z",
            "vendor": {
              "id": "2a3b4c5d-6e7f-4809-91a2-b3c4d5e6f708",
              "name": "Acme Panel Supply"
            }
          },
          "receipt": {
            "id": "a2b3c4d5-e6f7-4081-92a3-b4c5d6e7f809",
            "lines": [
              {
                "line_id": "91a2b3c4-d5e6-4f70-8192-a3b4c5d6e7f8",
                "quantity": 8.0
              }
            ],
            "packing_slip_ref": "PS-20931",
            "received_at": "2026-10-06T14:10:00Z"
          }
        },
        "properties": {
          "purchase_order": {
            "$ref": "#/components/schemas/PurchaseOrderOut"
          },
          "receipt": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ReceiptOut"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "purchase_order"
        ],
        "title": "ReceiveResultOut",
        "type": "object"
      },
      "Ref": {
        "description": "A pointer to one of the account's own records, with its current name.",
        "example": {
          "id": "7a1e2f30-9c4d-4b5e-8f60-1a2b3c4d5e6f",
          "name": "Production"
        },
        "properties": {
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name"
          }
        },
        "required": [
          "id"
        ],
        "title": "Ref",
        "type": "object"
      },
      "SectionCreateIn": {
        "example": {
          "name": "Kitchen cabinets"
        },
        "properties": {
          "name": {
            "maxLength": 255,
            "minLength": 1,
            "title": "Name",
            "type": "string"
          }
        },
        "required": [
          "name"
        ],
        "title": "SectionCreateIn",
        "type": "object"
      },
      "SectionOut": {
        "example": {
          "created_at": "2026-10-01T15:04:00Z",
          "estimate_id": "4d3c2b1a-0f9e-4d8c-8b7a-6f5e4d3c2b1a",
          "id": "9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
          "name": "Kitchen cabinets",
          "order": 1,
          "updated_at": "2026-10-01T15:04:00Z"
        },
        "properties": {
          "created_at": {
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "estimate_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Estimate Id"
          },
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "invoice_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Invoice Id"
          },
          "name": {
            "title": "Name",
            "type": "string"
          },
          "order": {
            "title": "Order",
            "type": "integer"
          },
          "updated_at": {
            "format": "date-time",
            "title": "Updated At",
            "type": "string"
          }
        },
        "required": [
          "id",
          "name",
          "order",
          "created_at",
          "updated_at"
        ],
        "title": "SectionOut",
        "type": "object"
      },
      "SendIn": {
        "example": {
          "contact_ids": [
            "b2d4e6f8-1a3c-5e7b-9d0f-2a4c6e8b0d1f"
          ],
          "message": "Hi Dana, here is the estimate we talked through on Tuesday.",
          "subject": "Your kitchen estimate"
        },
        "properties": {
          "contact_ids": {
            "description": "Contacts of this account, from GET /v1/contacts. Each gets their own email and link.",
            "items": {
              "format": "uuid",
              "type": "string"
            },
            "maxItems": 20,
            "minItems": 1,
            "title": "Contact Ids",
            "type": "array"
          },
          "message": {
            "anyOf": [
              {
                "maxLength": 10000,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Shown above the link in the email.",
            "title": "Message"
          },
          "subject": {
            "anyOf": [
              {
                "maxLength": 255,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Subject"
          }
        },
        "required": [
          "contact_ids"
        ],
        "title": "SendIn",
        "type": "object"
      },
      "SendResult": {
        "example": {
          "failed": [],
          "sent_count": 1,
          "thread_ids": [
            "8e7d6c5b-4a39-4281-9f0e-1d2c3b4a5968"
          ],
          "total_recipients": 1
        },
        "properties": {
          "failed": {
            "description": "Recipients the mailbox did not send to, with the reason.",
            "items": {
              "additionalProperties": true,
              "type": "object"
            },
            "title": "Failed",
            "type": "array"
          },
          "sent_count": {
            "title": "Sent Count",
            "type": "integer"
          },
          "thread_ids": {
            "description": "The email conversation opened per recipient.",
            "items": {
              "format": "uuid",
              "type": "string"
            },
            "title": "Thread Ids",
            "type": "array"
          },
          "total_recipients": {
            "title": "Total Recipients",
            "type": "integer"
          }
        },
        "required": [
          "sent_count",
          "total_recipients"
        ],
        "title": "SendResult",
        "type": "object"
      },
      "SimpleStatusOut": {
        "description": "A task, estimate or invoice status.",
        "example": {
          "color": "#2f6fb0",
          "id": "0b6f8e2a-4d1c-4a7e-9b3f-5c2d1e0f9a8b",
          "is_default": false,
          "locks_editing": true,
          "name": "Sent"
        },
        "properties": {
          "color": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Color"
          },
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "is_complete": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "Tasks: whether this status means done.",
            "title": "Is Complete"
          },
          "is_default": {
            "default": false,
            "title": "Is Default",
            "type": "boolean"
          },
          "locks_editing": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "Estimates and invoices: whether a document in this status can no longer be edited.",
            "title": "Locks Editing"
          },
          "name": {
            "title": "Name",
            "type": "string"
          }
        },
        "required": [
          "id",
          "name"
        ],
        "title": "SimpleStatusOut",
        "type": "object"
      },
      "StockItemOut": {
        "description": "One way a material is bought: a size, a pack, a part number.",
        "example": {
          "created_at": "2026-08-14T10:00:00Z",
          "currency": "USD",
          "id": "5d6e7f80-91a2-4b3c-8d4e-5f60718293a4",
          "is_active": true,
          "is_default": true,
          "lot_tracked": false,
          "manufacturer_sku": "WM-34-4997",
          "material_id": "4c5d6e7f-8091-4a2b-9c3d-4e5f60718293",
          "name": "49 x 97 sheet",
          "on_hand": 23.0,
          "preferred_vendor_id": "2a3b4c5d-6e7f-4809-91a2-b3c4d5e6f708",
          "reorder_point": 10.0,
          "reorder_qty": 40.0,
          "sku": "MEL-4997",
          "standard_cost": "42.50",
          "unit": "sheet",
          "updated_at": "2026-09-30T16:20:00Z",
          "values": [
            {
              "key": "size",
              "label": "Size",
              "text": "49 x 97"
            }
          ]
        },
        "properties": {
          "barcode": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Barcode"
          },
          "created_at": {
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "currency": {
            "default": "USD",
            "title": "Currency",
            "type": "string"
          },
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "is_active": {
            "default": true,
            "title": "Is Active",
            "type": "boolean"
          },
          "is_default": {
            "default": false,
            "title": "Is Default",
            "type": "boolean"
          },
          "lot_tracked": {
            "default": false,
            "title": "Lot Tracked",
            "type": "boolean"
          },
          "manufacturer_sku": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Manufacturer Sku"
          },
          "material_id": {
            "format": "uuid",
            "title": "Material Id",
            "type": "string"
          },
          "material_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Present when the stock item is read on its own.",
            "title": "Material Name"
          },
          "name": {
            "title": "Name",
            "type": "string"
          },
          "on_hand": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "description": "Stock on hand when the account tracks inventory.",
            "title": "On Hand"
          },
          "preferred_vendor_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Preferred Vendor Id"
          },
          "reorder_point": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Reorder Point"
          },
          "reorder_qty": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Reorder Qty"
          },
          "sku": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Sku"
          },
          "standard_cost": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Decimal string. Null when not set or the acting user cannot see costs.",
            "title": "Standard Cost"
          },
          "unit": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Unit"
          },
          "updated_at": {
            "format": "date-time",
            "title": "Updated At",
            "type": "string"
          },
          "values": {
            "items": {
              "$ref": "#/components/schemas/AttributeValueOut"
            },
            "title": "Values",
            "type": "array"
          }
        },
        "required": [
          "id",
          "material_id",
          "name",
          "created_at",
          "updated_at"
        ],
        "title": "StockItemOut",
        "type": "object"
      },
      "TaskCreateIn": {
        "example": {
          "assignee_user_ids": [
            "e1d2c3b4-a596-4877-8695-a4b3c2d1e0f9"
          ],
          "department_ids": [
            "4d5e6f70-8192-4a3b-9c4d-5e6f708192a3"
          ],
          "description": "Satin nickel or matte black.",
          "due_date": "2026-10-14",
          "due_time": "2026-10-14T15:00:00Z",
          "title": "Confirm hinge finish with the customer"
        },
        "properties": {
          "assignee_user_ids": {
            "description": "At least one person, from GET /v1/meta/users.",
            "items": {
              "format": "uuid",
              "type": "string"
            },
            "minItems": 1,
            "title": "Assignee User Ids",
            "type": "array"
          },
          "department_ids": {
            "description": "Optional, from GET /v1/meta/departments. The first is the primary department.",
            "items": {
              "format": "uuid",
              "type": "string"
            },
            "title": "Department Ids",
            "type": "array"
          },
          "description": {
            "anyOf": [
              {
                "maxLength": 255,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description"
          },
          "due_date": {
            "format": "date",
            "title": "Due Date",
            "type": "string"
          },
          "due_time": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Optional time on the due date, with a time zone offset.",
            "title": "Due Time"
          },
          "status_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "From GET /v1/meta/task-statuses. Defaults to the account's Incomplete status.",
            "title": "Status Id"
          },
          "team_ids": {
            "description": "Optional. Each team must belong to one of the departments sent.",
            "items": {
              "format": "uuid",
              "type": "string"
            },
            "title": "Team Ids",
            "type": "array"
          },
          "title": {
            "maxLength": 255,
            "minLength": 1,
            "title": "Title",
            "type": "string"
          }
        },
        "required": [
          "title",
          "due_date",
          "assignee_user_ids"
        ],
        "title": "TaskCreateIn",
        "type": "object"
      },
      "TaskJobRef": {
        "description": "The job a task is on.",
        "example": {
          "id": "3f9a1c77-5e3b-4a02-9d8e-2c7b6a1f0e4d",
          "name": "Whitfield kitchen remodel",
          "reference": "J1042"
        },
        "properties": {
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name"
          },
          "reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The job number people use, e.g. J1042.",
            "title": "Reference"
          }
        },
        "required": [
          "id"
        ],
        "title": "TaskJobRef",
        "type": "object"
      },
      "TaskOut": {
        "example": {
          "assignees": [
            {
              "id": "e1d2c3b4-a596-4877-8695-a4b3c2d1e0f9",
              "name": "Mia Lead"
            }
          ],
          "created_at": "2026-10-05T09:12:44.001Z",
          "created_by": {
            "id": "e1d2c3b4-a596-4877-8695-a4b3c2d1e0f9",
            "name": "Mia Lead"
          },
          "departments": [
            {
              "id": "4d5e6f70-8192-4a3b-9c4d-5e6f708192a3",
              "name": "Office"
            }
          ],
          "description": "Satin nickel or matte black.",
          "due_date": "2026-10-14",
          "due_time": "2026-10-14T15:00:00+00:00",
          "id": "9e8d7c6b-5a49-4382-9170-6f5e4d3c2b1a",
          "job": {
            "id": "3f9a1c77-5e3b-4a02-9d8e-2c7b6a1f0e4d",
            "name": "Whitfield kitchen remodel",
            "reference": "J1042"
          },
          "status": {
            "id": "0b6f8e2a-4d1c-4a7e-9b3f-5c2d1e0f9a8b",
            "is_complete": false,
            "name": "Incomplete"
          },
          "teams": [],
          "title": "Confirm hinge finish with the customer",
          "updated_at": "2026-10-05T09:12:44.001Z"
        },
        "properties": {
          "assignees": {
            "description": "The people the task is assigned to.",
            "items": {
              "$ref": "#/components/schemas/Ref"
            },
            "title": "Assignees",
            "type": "array"
          },
          "completed_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When it was completed. Null while it is open.",
            "title": "Completed At"
          },
          "created_at": {
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "created_by": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Ref"
              },
              {
                "type": "null"
              }
            ],
            "description": "Null for tasks an automation made."
          },
          "departments": {
            "items": {
              "$ref": "#/components/schemas/Ref"
            },
            "title": "Departments",
            "type": "array"
          },
          "description": {
            "default": "",
            "title": "Description",
            "type": "string"
          },
          "due_date": {
            "anyOf": [
              {
                "format": "date",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Due Date"
          },
          "due_time": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "A time on the due date, when one was set.",
            "title": "Due Time"
          },
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "job": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/TaskJobRef"
              },
              {
                "type": "null"
              }
            ],
            "description": "Null for a task that is not on a job."
          },
          "status": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/TaskStatusRef"
              },
              {
                "type": "null"
              }
            ]
          },
          "teams": {
            "items": {
              "$ref": "#/components/schemas/Ref"
            },
            "title": "Teams",
            "type": "array"
          },
          "title": {
            "title": "Title",
            "type": "string"
          },
          "updated_at": {
            "format": "date-time",
            "title": "Updated At",
            "type": "string"
          }
        },
        "required": [
          "id",
          "title",
          "created_at",
          "updated_at"
        ],
        "title": "TaskOut",
        "type": "object"
      },
      "TaskPage": {
        "example": {
          "data": [
            {
              "assignees": [
                {
                  "id": "e1d2c3b4-a596-4877-8695-a4b3c2d1e0f9",
                  "name": "Mia Lead"
                }
              ],
              "created_at": "2026-10-05T09:12:44.001Z",
              "created_by": {
                "id": "e1d2c3b4-a596-4877-8695-a4b3c2d1e0f9",
                "name": "Mia Lead"
              },
              "departments": [
                {
                  "id": "4d5e6f70-8192-4a3b-9c4d-5e6f708192a3",
                  "name": "Office"
                }
              ],
              "description": "Satin nickel or matte black.",
              "due_date": "2026-10-14",
              "due_time": "2026-10-14T15:00:00+00:00",
              "id": "9e8d7c6b-5a49-4382-9170-6f5e4d3c2b1a",
              "job": {
                "id": "3f9a1c77-5e3b-4a02-9d8e-2c7b6a1f0e4d",
                "name": "Whitfield kitchen remodel",
                "reference": "J1042"
              },
              "status": {
                "id": "0b6f8e2a-4d1c-4a7e-9b3f-5c2d1e0f9a8b",
                "is_complete": false,
                "name": "Incomplete"
              },
              "teams": [],
              "title": "Confirm hinge finish with the customer",
              "updated_at": "2026-10-05T09:12:44.001Z"
            }
          ],
          "has_more": false,
          "next_cursor": "eyJ2IjoiMjAyNi0xMC0wNVQwOToxMjo0NC4wMDErMDA6MDAifQ.1a2b3c4d5e6f"
        },
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/TaskOut"
            },
            "title": "Data",
            "type": "array"
          },
          "has_more": {
            "default": false,
            "title": "Has More",
            "type": "boolean"
          },
          "next_cursor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Pass as `cursor` to get the next page. Null at the end.",
            "title": "Next Cursor"
          }
        },
        "title": "TaskPage",
        "type": "object"
      },
      "TaskStatusRef": {
        "description": "A task status, from GET /v1/meta/task-statuses.",
        "example": {
          "id": "0b6f8e2a-4d1c-4a7e-9b3f-5c2d1e0f9a8b",
          "is_complete": false,
          "name": "Incomplete"
        },
        "properties": {
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "is_complete": {
            "default": false,
            "description": "Whether this status means done.",
            "title": "Is Complete",
            "type": "boolean"
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name"
          }
        },
        "required": [
          "id"
        ],
        "title": "TaskStatusRef",
        "type": "object"
      },
      "TaskUpdateIn": {
        "description": "Only the fields you send change. Lists replace what is there.",
        "example": {
          "assignee_user_ids": [
            "e1d2c3b4-a596-4877-8695-a4b3c2d1e0f9",
            "0c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f"
          ],
          "due_date": "2026-10-16"
        },
        "properties": {
          "assignee_user_ids": {
            "anyOf": [
              {
                "items": {
                  "format": "uuid",
                  "type": "string"
                },
                "minItems": 1,
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Replaces the assignees. At least one.",
            "title": "Assignee User Ids"
          },
          "department_ids": {
            "anyOf": [
              {
                "items": {
                  "format": "uuid",
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Replaces the departments.",
            "title": "Department Ids"
          },
          "description": {
            "anyOf": [
              {
                "maxLength": 255,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description"
          },
          "due_date": {
            "anyOf": [
              {
                "format": "date",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Due Date"
          },
          "due_time": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Send null to clear the time.",
            "title": "Due Time"
          },
          "status_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "From GET /v1/meta/task-statuses. A status that means done also sets completed_at.",
            "title": "Status Id"
          },
          "team_ids": {
            "anyOf": [
              {
                "items": {
                  "format": "uuid",
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Replaces the teams.",
            "title": "Team Ids"
          },
          "title": {
            "anyOf": [
              {
                "maxLength": 255,
                "minLength": 1,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Title"
          }
        },
        "title": "TaskUpdateIn",
        "type": "object"
      },
      "TestSentOut": {
        "example": {
          "delivery_id": "8f7e6d5c-4b3a-4291-8a7b-6c5d4e3f2a1b"
        },
        "properties": {
          "delivery_id": {
            "format": "uuid",
            "title": "Delivery Id",
            "type": "string"
          }
        },
        "required": [
          "delivery_id"
        ],
        "title": "TestSentOut",
        "type": "object"
      },
      "ThreadOut": {
        "example": {
          "category": "project_update",
          "channel": "email",
          "created_at": "2026-10-05T16:40:00+00:00",
          "has_customer_reply": true,
          "id": "6b5a4c3d-2e1f-4a0b-9c8d-7e6f5a4b3c2d",
          "last_message_at": "2026-10-06T14:02:11+00:00",
          "message_count": 3,
          "subject": "Your install date"
        },
        "properties": {
          "archived_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Archived At"
          },
          "category": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "project_update for one sent through the API; estimate, invoice, payment, work_order, calendar or signature_packet for the app's own.",
            "title": "Category"
          },
          "channel": {
            "description": "email or sms.",
            "title": "Channel",
            "type": "string"
          },
          "created_at": {
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "has_customer_reply": {
            "default": false,
            "title": "Has Customer Reply",
            "type": "boolean"
          },
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "last_message_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Message At"
          },
          "message_count": {
            "default": 0,
            "title": "Message Count",
            "type": "integer"
          },
          "subject": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Subject"
          }
        },
        "required": [
          "id",
          "channel",
          "created_at"
        ],
        "title": "ThreadOut",
        "type": "object"
      },
      "ThreadPage": {
        "example": {
          "data": [
            {
              "category": "project_update",
              "channel": "email",
              "created_at": "2026-10-05T16:40:00+00:00",
              "has_customer_reply": true,
              "id": "6b5a4c3d-2e1f-4a0b-9c8d-7e6f5a4b3c2d",
              "last_message_at": "2026-10-06T14:02:11+00:00",
              "message_count": 3,
              "subject": "Your install date"
            }
          ],
          "has_more": false
        },
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/ThreadOut"
            },
            "title": "Data",
            "type": "array"
          },
          "has_more": {
            "default": false,
            "title": "Has More",
            "type": "boolean"
          },
          "next_cursor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Pass as `cursor` to get the next page. Null at the end.",
            "title": "Next Cursor"
          }
        },
        "title": "ThreadPage",
        "type": "object"
      },
      "TimeEntryOut": {
        "example": {
          "clock_in": "2026-10-05T13:02:00Z",
          "clock_out": "2026-10-05T16:30:00Z",
          "created_at": "2026-10-05T13:02:00Z",
          "department": {
            "id": "f0e1d2c3-b4a5-4697-8877-665544332211",
            "name": "Cut"
          },
          "duration_minutes": 208,
          "entry_type": "clock",
          "id": "f4a5b6c7-d8e9-4fa0-b1c2-d3e4f5a6b7c8",
          "is_running": false,
          "job": {
            "id": "3f9a1c77-5e3b-4a02-9d8e-2c7b6a1f0e4d",
            "name": "Whitfield kitchen remodel",
            "reference": "J1042"
          },
          "updated_at": "2026-10-05T16:30:00Z",
          "user": {
            "id": "e1d2c3b4-a596-4877-8695-a4b3c2d1e0f9",
            "name": "Sam Floor"
          },
          "work_order": {
            "id": "6e2b9a14-3c5d-4f70-8a91-b2c3d4e5f607",
            "name": "Kitchen boxes",
            "reference": "W318"
          },
          "work_order_status": {
            "id": "9c1d2e3f-4a5b-4c6d-8e7f-0a1b2c3d4e5f",
            "name": "Cutting"
          }
        },
        "properties": {
          "clock_in": {
            "format": "date-time",
            "title": "Clock In",
            "type": "string"
          },
          "clock_out": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Null while the timer is still running.",
            "title": "Clock Out"
          },
          "created_at": {
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "department": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Ref"
              },
              {
                "type": "null"
              }
            ]
          },
          "duration_minutes": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Duration Minutes"
          },
          "entry_type": {
            "default": "clock",
            "description": "clock for a punch on the kiosk or app, manual for one typed in.",
            "title": "Entry Type",
            "type": "string"
          },
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "is_running": {
            "default": false,
            "title": "Is Running",
            "type": "boolean"
          },
          "job": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/TimeJobRef"
              },
              {
                "type": "null"
              }
            ]
          },
          "notes": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Notes"
          },
          "updated_at": {
            "format": "date-time",
            "title": "Updated At",
            "type": "string"
          },
          "user": {
            "$ref": "#/components/schemas/Ref"
          },
          "work_order": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/TimeJobRef"
              },
              {
                "type": "null"
              }
            ]
          },
          "work_order_status": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Ref"
              },
              {
                "type": "null"
              }
            ],
            "description": "The step of the work order the time was spent on."
          }
        },
        "required": [
          "id",
          "user",
          "clock_in",
          "created_at",
          "updated_at"
        ],
        "title": "TimeEntryOut",
        "type": "object"
      },
      "TimeEntryPage": {
        "example": {
          "data": [
            {
              "clock_in": "2026-10-05T13:02:00Z",
              "clock_out": "2026-10-05T16:30:00Z",
              "created_at": "2026-10-05T13:02:00Z",
              "department": {
                "id": "f0e1d2c3-b4a5-4697-8877-665544332211",
                "name": "Cut"
              },
              "duration_minutes": 208,
              "entry_type": "clock",
              "id": "f4a5b6c7-d8e9-4fa0-b1c2-d3e4f5a6b7c8",
              "is_running": false,
              "job": {
                "id": "3f9a1c77-5e3b-4a02-9d8e-2c7b6a1f0e4d",
                "name": "Whitfield kitchen remodel",
                "reference": "J1042"
              },
              "updated_at": "2026-10-05T16:30:00Z",
              "user": {
                "id": "e1d2c3b4-a596-4877-8695-a4b3c2d1e0f9",
                "name": "Sam Floor"
              },
              "work_order": {
                "id": "6e2b9a14-3c5d-4f70-8a91-b2c3d4e5f607",
                "name": "Kitchen boxes",
                "reference": "W318"
              },
              "work_order_status": {
                "id": "9c1d2e3f-4a5b-4c6d-8e7f-0a1b2c3d4e5f",
                "name": "Cutting"
              }
            }
          ],
          "has_more": true,
          "next_cursor": "eyJ2IjoiMjAyNi0xMC0wNVQxMzowMjowMCswMDowMCJ9.2f4c1e0a9b7d"
        },
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/TimeEntryOut"
            },
            "title": "Data",
            "type": "array"
          },
          "has_more": {
            "default": false,
            "title": "Has More",
            "type": "boolean"
          },
          "next_cursor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Pass as `cursor` to get the next page. Null at the end.",
            "title": "Next Cursor"
          }
        },
        "title": "TimeEntryPage",
        "type": "object"
      },
      "TimeJobRef": {
        "properties": {
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name"
          },
          "reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Reference"
          }
        },
        "required": [
          "id"
        ],
        "title": "TimeJobRef",
        "type": "object"
      },
      "UploadCompleteIn": {
        "example": {
          "upload_token": "eyJ2IjoxLCJqIjoiM2Y5YTFjNzcifQ.6f1d0c2b9a8e7d6c5b4a39281706f5e4d3c2b1a0"
        },
        "properties": {
          "upload_token": {
            "description": "From POST /v1/jobs/{job_id}/files/upload-url.",
            "maxLength": 4096,
            "minLength": 10,
            "title": "Upload Token",
            "type": "string"
          }
        },
        "required": [
          "upload_token"
        ],
        "title": "UploadCompleteIn",
        "type": "object"
      },
      "UploadUrlIn": {
        "example": {
          "content_type": "application/pdf",
          "folder_id": "1f2e3d4c-5b6a-4798-8a7b-6c5d4e3f2a1b",
          "name": "Kitchen elevation.pdf",
          "size_bytes": 482133
        },
        "properties": {
          "content_type": {
            "description": "The MIME type. Send exactly this as Content-Type on the PUT.",
            "maxLength": 255,
            "minLength": 1,
            "title": "Content Type",
            "type": "string"
          },
          "folder_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "A folder on the job, from a file's `folder.id`. Defaults to the job's first folder.",
            "title": "Folder Id"
          },
          "name": {
            "description": "The file name with its extension. The extension decides whether the type is accepted.",
            "maxLength": 255,
            "minLength": 1,
            "title": "Name",
            "type": "string"
          },
          "size_bytes": {
            "description": "The size in bytes. At most 104857600 (100 MB).",
            "maximum": 104857600.0,
            "minimum": 1.0,
            "title": "Size Bytes",
            "type": "integer"
          }
        },
        "required": [
          "name",
          "content_type",
          "size_bytes"
        ],
        "title": "UploadUrlIn",
        "type": "object"
      },
      "UploadUrlOut": {
        "example": {
          "expires_at": "2026-10-06T09:42:44+00:00",
          "folder": {
            "id": "1f2e3d4c-5b6a-4798-8a7b-6c5d4e3f2a1b",
            "name": "Drawings"
          },
          "max_size_bytes": 104857600,
          "method": "PUT",
          "required_headers": {
            "Content-Type": "application/pdf"
          },
          "upload_token": "eyJ2IjoxLCJqIjoiM2Y5YTFjNzcifQ.6f1d0c2b9a8e7d6c5b4a39281706f5e4d3c2b1a0",
          "upload_url": "https://storage.googleapis.com/ws-tenant-5c8d2e1f/job/3f9a1c77/4a1b.pdf?X-Goog-Signature=..."
        },
        "properties": {
          "expires_at": {
            "description": "When upload_url stops accepting a PUT (about 30 minutes).",
            "format": "date-time",
            "title": "Expires At",
            "type": "string"
          },
          "folder": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Ref"
              },
              {
                "type": "null"
              }
            ],
            "description": "The folder the file will go in."
          },
          "max_size_bytes": {
            "title": "Max Size Bytes",
            "type": "integer"
          },
          "method": {
            "default": "PUT",
            "title": "Method",
            "type": "string"
          },
          "required_headers": {
            "additionalProperties": {
              "type": "string"
            },
            "description": "Send these headers on the PUT, exactly.",
            "title": "Required Headers",
            "type": "object"
          },
          "upload_token": {
            "description": "Opaque. Send it to POST /v1/files/complete once the PUT succeeds. Valid for 24 hours.",
            "title": "Upload Token",
            "type": "string"
          },
          "upload_url": {
            "description": "PUT the raw bytes here, before expires_at.",
            "title": "Upload Url",
            "type": "string"
          }
        },
        "required": [
          "upload_url",
          "required_headers",
          "expires_at",
          "upload_token",
          "max_size_bytes"
        ],
        "title": "UploadUrlOut",
        "type": "object"
      },
      "UsageDay": {
        "properties": {
          "api_calls": {
            "title": "Api Calls",
            "type": "integer"
          },
          "day": {
            "format": "date",
            "title": "Day",
            "type": "string"
          },
          "mcp_calls": {
            "title": "Mcp Calls",
            "type": "integer"
          },
          "webhook_deliveries": {
            "title": "Webhook Deliveries",
            "type": "integer"
          }
        },
        "required": [
          "day",
          "api_calls",
          "webhook_deliveries",
          "mcp_calls"
        ],
        "title": "UsageDay",
        "type": "object"
      },
      "UsageLimits": {
        "properties": {
          "bill_overage": {
            "title": "Bill Overage",
            "type": "boolean"
          },
          "burst": {
            "title": "Burst",
            "type": "integer"
          },
          "monthly_hard_cap_calls": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Monthly Hard Cap Calls"
          },
          "monthly_included_calls": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Monthly Included Calls"
          },
          "requests_per_day": {
            "title": "Requests Per Day",
            "type": "integer"
          },
          "requests_per_minute": {
            "title": "Requests Per Minute",
            "type": "integer"
          }
        },
        "required": [
          "requests_per_minute",
          "burst",
          "requests_per_day",
          "monthly_included_calls",
          "monthly_hard_cap_calls",
          "bill_overage"
        ],
        "title": "UsageLimits",
        "type": "object"
      },
      "UsageOut": {
        "description": "Calls this calendar month (UTC) against what the plan includes.",
        "example": {
          "api_calls": 20950,
          "billable_calls": 21480,
          "days": [
            {
              "api_calls": 812,
              "day": "2026-10-06",
              "mcp_calls": 40,
              "webhook_deliveries": 31
            }
          ],
          "included_calls": 20000,
          "limits": {
            "bill_overage": true,
            "burst": 600,
            "monthly_hard_cap_calls": 100000,
            "monthly_included_calls": 20000,
            "requests_per_day": 50000,
            "requests_per_minute": 300
          },
          "mcp_calls": 1200,
          "month": "2026-10",
          "overage_calls": 1480,
          "overage_units": 2,
          "overage_usd": "10.00",
          "webhook_deliveries": 530
        },
        "properties": {
          "api_calls": {
            "title": "Api Calls",
            "type": "integer"
          },
          "billable_calls": {
            "description": "API calls plus first webhook deliveries this month. MCP calls are already inside api_calls.",
            "title": "Billable Calls",
            "type": "integer"
          },
          "days": {
            "description": "The last 31 days, oldest first, days with no calls included as zeros.",
            "items": {
              "$ref": "#/components/schemas/UsageDay"
            },
            "title": "Days",
            "type": "array"
          },
          "included_calls": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Included Calls"
          },
          "limits": {
            "$ref": "#/components/schemas/UsageLimits"
          },
          "mcp_calls": {
            "description": "The part of api_calls made through the MCP server.",
            "title": "Mcp Calls",
            "type": "integer"
          },
          "month": {
            "description": "YYYY-MM, UTC.",
            "title": "Month",
            "type": "string"
          },
          "overage_calls": {
            "title": "Overage Calls",
            "type": "integer"
          },
          "overage_units": {
            "description": "Blocks of 1,000 calls over the included amount, rounded up.",
            "title": "Overage Units",
            "type": "integer"
          },
          "overage_usd": {
            "description": "Overage so far at $5 per 1,000 calls, as a decimal string. Zero when overage is not billed.",
            "title": "Overage Usd",
            "type": "string"
          },
          "webhook_deliveries": {
            "title": "Webhook Deliveries",
            "type": "integer"
          }
        },
        "required": [
          "month",
          "billable_calls",
          "api_calls",
          "webhook_deliveries",
          "mcp_calls",
          "included_calls",
          "overage_calls",
          "overage_units",
          "overage_usd",
          "limits",
          "days"
        ],
        "title": "UsageOut",
        "type": "object"
      },
      "UserOut": {
        "description": "An active member of the account. No email: the id is what assignments need.",
        "example": {
          "id": "e1d2c3b4-a596-4877-8695-a4b3c2d1e0f9",
          "is_project_manager": true,
          "name": "Mia Lead",
          "role": "manager"
        },
        "properties": {
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "is_project_manager": {
            "default": false,
            "title": "Is Project Manager",
            "type": "boolean"
          },
          "name": {
            "title": "Name",
            "type": "string"
          },
          "role": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "production, office, manager, admin or owner.",
            "title": "Role"
          }
        },
        "required": [
          "id",
          "name"
        ],
        "title": "UserOut",
        "type": "object"
      },
      "VendorContactIn": {
        "properties": {
          "email": {
            "anyOf": [
              {
                "maxLength": 255,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Email"
          },
          "first_name": {
            "maxLength": 50,
            "minLength": 1,
            "title": "First Name",
            "type": "string"
          },
          "last_name": {
            "anyOf": [
              {
                "maxLength": 50,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Name"
          },
          "phone_number": {
            "anyOf": [
              {
                "maxLength": 32,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Phone Number"
          }
        },
        "required": [
          "first_name"
        ],
        "title": "VendorContactIn",
        "type": "object"
      },
      "VendorContactOut": {
        "properties": {
          "email": {
            "default": "",
            "title": "Email",
            "type": "string"
          },
          "first_name": {
            "default": "",
            "title": "First Name",
            "type": "string"
          },
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "last_name": {
            "default": "",
            "title": "Last Name",
            "type": "string"
          },
          "phone_number": {
            "default": "",
            "title": "Phone Number",
            "type": "string"
          }
        },
        "required": [
          "id"
        ],
        "title": "VendorContactOut",
        "type": "object"
      },
      "VendorCreateIn": {
        "example": {
          "address": {
            "city": "Austin",
            "line1": "400 Mill Road",
            "postal_code": "78702",
            "state": "TX"
          },
          "contacts": [
            {
              "email": "orders@acmesupply.example.com",
              "first_name": "Lee",
              "last_name": "Park"
            }
          ],
          "lead_time_days": 5,
          "name": "Acme Panel Supply",
          "payment_terms_days": 30,
          "phone_number": "5125550100"
        },
        "properties": {
          "address": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/AddressIn"
              },
              {
                "type": "null"
              }
            ]
          },
          "contacts": {
            "items": {
              "$ref": "#/components/schemas/VendorContactIn"
            },
            "title": "Contacts",
            "type": "array"
          },
          "lead_time_days": {
            "anyOf": [
              {
                "maximum": 365.0,
                "minimum": 0.0,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Lead Time Days"
          },
          "minimum_order_amount": {
            "anyOf": [
              {
                "minimum": 0.0,
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Minimum Order Amount"
          },
          "name": {
            "maxLength": 255,
            "minLength": 1,
            "title": "Name",
            "type": "string"
          },
          "notes": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Notes"
          },
          "payment_terms_days": {
            "anyOf": [
              {
                "maximum": 365.0,
                "minimum": 0.0,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Payment Terms Days"
          },
          "phone_number": {
            "anyOf": [
              {
                "maxLength": 32,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Phone Number"
          },
          "website": {
            "anyOf": [
              {
                "maxLength": 255,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Website"
          }
        },
        "required": [
          "name"
        ],
        "title": "VendorCreateIn",
        "type": "object"
      },
      "VendorOut": {
        "example": {
          "address": {
            "city": "Austin",
            "line1": "400 Mill Road",
            "postal_code": "78702",
            "state": "TX"
          },
          "contacts": [
            {
              "email": "orders@acmesupply.example.com",
              "first_name": "Lee",
              "id": "b2d4e6f8-1a3c-5e7b-9d0f-2a4c6e8b0d1f",
              "last_name": "Park",
              "phone_number": "5125550199"
            }
          ],
          "created_at": "2026-06-02T13:00:00Z",
          "currency": "USD",
          "id": "2a3b4c5d-6e7f-4809-91a2-b3c4d5e6f708",
          "is_active": true,
          "lead_time_days": 5,
          "minimum_order_amount": "250.00",
          "name": "Acme Panel Supply",
          "payment_terms_days": 30,
          "phone_number": "5125550100",
          "reference": "V12",
          "updated_at": "2026-09-28T08:45:00Z",
          "website": "https://acmesupply.example.com"
        },
        "properties": {
          "address": {
            "$ref": "#/components/schemas/AddressOut"
          },
          "archived_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Archived At"
          },
          "contacts": {
            "items": {
              "$ref": "#/components/schemas/VendorContactOut"
            },
            "title": "Contacts",
            "type": "array"
          },
          "created_at": {
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "currency": {
            "default": "USD",
            "title": "Currency",
            "type": "string"
          },
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "is_active": {
            "default": true,
            "title": "Is Active",
            "type": "boolean"
          },
          "lead_time_days": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Days from order to delivery. Null when unknown.",
            "title": "Lead Time Days"
          },
          "minimum_order_amount": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Decimal string. Null when not set or the acting user cannot see costs.",
            "title": "Minimum Order Amount"
          },
          "name": {
            "title": "Name",
            "type": "string"
          },
          "notes": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Notes"
          },
          "payment_terms_days": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Net days, e.g. 30.",
            "title": "Payment Terms Days"
          },
          "phone_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Phone Number"
          },
          "reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The supplier number, e.g. V12.",
            "title": "Reference"
          },
          "updated_at": {
            "format": "date-time",
            "title": "Updated At",
            "type": "string"
          },
          "website": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Website"
          }
        },
        "required": [
          "id",
          "name",
          "address",
          "created_at",
          "updated_at"
        ],
        "title": "VendorOut",
        "type": "object"
      },
      "VendorPage": {
        "example": {
          "data": [
            {
              "address": {
                "city": "Austin",
                "line1": "400 Mill Road",
                "postal_code": "78702",
                "state": "TX"
              },
              "contacts": [
                {
                  "email": "orders@acmesupply.example.com",
                  "first_name": "Lee",
                  "id": "b2d4e6f8-1a3c-5e7b-9d0f-2a4c6e8b0d1f",
                  "last_name": "Park",
                  "phone_number": "5125550199"
                }
              ],
              "created_at": "2026-06-02T13:00:00Z",
              "currency": "USD",
              "id": "2a3b4c5d-6e7f-4809-91a2-b3c4d5e6f708",
              "is_active": true,
              "lead_time_days": 5,
              "minimum_order_amount": "250.00",
              "name": "Acme Panel Supply",
              "payment_terms_days": 30,
              "phone_number": "5125550100",
              "reference": "V12",
              "updated_at": "2026-09-28T08:45:00Z",
              "website": "https://acmesupply.example.com"
            }
          ],
          "has_more": false,
          "next_cursor": "eyJ2IjoiMjAyNi0wNi0wMlQxMzowMDowMCswMDowMCJ9.1e0a9b7d2f4c"
        },
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/VendorOut"
            },
            "title": "Data",
            "type": "array"
          },
          "has_more": {
            "default": false,
            "title": "Has More",
            "type": "boolean"
          },
          "next_cursor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Pass as `cursor` to get the next page. Null at the end.",
            "title": "Next Cursor"
          }
        },
        "title": "VendorPage",
        "type": "object"
      },
      "VendorUpdateIn": {
        "description": "Only the fields you send change. Contacts and archiving are managed\nin the app.",
        "example": {
          "lead_time_days": 7,
          "payment_terms_days": 45
        },
        "properties": {
          "address": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/AddressIn"
              },
              {
                "type": "null"
              }
            ]
          },
          "lead_time_days": {
            "anyOf": [
              {
                "maximum": 365.0,
                "minimum": 0.0,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Lead Time Days"
          },
          "minimum_order_amount": {
            "anyOf": [
              {
                "minimum": 0.0,
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Minimum Order Amount"
          },
          "name": {
            "anyOf": [
              {
                "maxLength": 255,
                "minLength": 1,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name"
          },
          "notes": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Notes"
          },
          "payment_terms_days": {
            "anyOf": [
              {
                "maximum": 365.0,
                "minimum": 0.0,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Payment Terms Days"
          },
          "phone_number": {
            "anyOf": [
              {
                "maxLength": 32,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Phone Number"
          },
          "website": {
            "anyOf": [
              {
                "maxLength": 255,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Website"
          }
        },
        "title": "VendorUpdateIn",
        "type": "object"
      },
      "WebhookEvent": {
        "description": "The body of every delivery.",
        "properties": {
          "api_version": {
            "type": "string"
          },
          "created_at": {
            "format": "date-time",
            "type": "string"
          },
          "data": {
            "properties": {
              "object": {
                "description": "A small summary of the record. Fetch `url` for the rest.",
                "type": "object"
              },
              "previous_attributes": {
                "description": "What changed, on status_changed events.",
                "type": "object"
              },
              "url": {
                "description": "The record in this API, read as the user your key acts as.",
                "type": "string"
              }
            },
            "type": "object"
          },
          "id": {
            "description": "Stable per event; use it to drop repeats.",
            "format": "uuid",
            "type": "string"
          },
          "livemode": {
            "description": "false for events from the sandbox.",
            "type": "boolean"
          },
          "object": {
            "enum": [
              "event"
            ],
            "type": "string"
          },
          "source": {
            "description": "What caused it: kind is ui, api, oauth, workflow or system; api_key_prefix when it was one of your keys.",
            "type": "object"
          },
          "tenant_id": {
            "format": "uuid",
            "type": "string"
          },
          "type": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "object",
          "type",
          "api_version",
          "created_at",
          "livemode",
          "tenant_id",
          "data"
        ],
        "title": "WebhookEvent",
        "type": "object"
      },
      "WorkOrderCreateIn": {
        "example": {
          "assigned_user_ids": [
            "e1d2c3b4-a596-4877-8695-a4b3c2d1e0f9"
          ],
          "due_date": "2026-11-02",
          "job_id": "3f9a1c77-5e3b-4a02-9d8e-2c7b6a1f0e4d",
          "name": "Kitchen boxes",
          "priority": 2,
          "schema_id": "b5c6d7e8-f9a0-4b1c-8d2e-3f4a5b6c7d8e",
          "type_id": "a4b5c6d7-e8f9-4a0b-9c1d-2e3f4a5b6c7d"
        },
        "properties": {
          "assigned_user_ids": {
            "anyOf": [
              {
                "items": {
                  "format": "uuid",
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Active users, from GET /v1/meta/users.",
            "title": "Assigned User Ids"
          },
          "due_date": {
            "anyOf": [
              {
                "format": "date",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Due Date"
          },
          "job_id": {
            "description": "A won job. An open opportunity may only carry a Prep work order.",
            "format": "uuid",
            "title": "Job Id",
            "type": "string"
          },
          "name": {
            "anyOf": [
              {
                "maxLength": 255,
                "minLength": 1,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Defaults to the template's name, else the type's.",
            "title": "Name"
          },
          "priority": {
            "anyOf": [
              {
                "maximum": 1000.0,
                "minimum": 0.0,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Priority"
          },
          "schema_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The template to build it from. Defaults to the type's current template.",
            "title": "Schema Id"
          },
          "type_id": {
            "description": "From GET /v1/meta/work-order-types.",
            "format": "uuid",
            "title": "Type Id",
            "type": "string"
          }
        },
        "required": [
          "job_id",
          "type_id"
        ],
        "title": "WorkOrderCreateIn",
        "type": "object"
      },
      "WorkOrderJobRef": {
        "properties": {
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name"
          },
          "reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The job number people use, e.g. J1042.",
            "title": "Reference"
          }
        },
        "required": [
          "id"
        ],
        "title": "WorkOrderJobRef",
        "type": "object"
      },
      "WorkOrderOut": {
        "example": {
          "assigned_user_ids": [
            "e1d2c3b4-a596-4877-8695-a4b3c2d1e0f9"
          ],
          "completion_pct": 40.0,
          "created_at": "2026-10-01T15:04:00Z",
          "due_date": "2026-11-02",
          "id": "6e2b9a14-3c5d-4f70-8a91-b2c3d4e5f607",
          "job": {
            "id": "3f9a1c77-5e3b-4a02-9d8e-2c7b6a1f0e4d",
            "name": "Whitfield kitchen remodel",
            "reference": "J1042"
          },
          "name": "Kitchen boxes",
          "priority": 2,
          "reference": "W318",
          "sections": [
            {
              "id": "c6d7e8f9-a0b1-4c2d-9e3f-4a5b6c7d8e9f",
              "name": "To do",
              "sort_order": 0,
              "status": {
                "color": "#6b7280",
                "id": "8b2f3a41-0d5e-4c6f-9a71-2b3c4d5e6f70",
                "is_complete": false,
                "name": "To do"
              }
            },
            {
              "department_id": "f0e1d2c3-b4a5-4697-8877-665544332211",
              "expected_end": "2026-10-22",
              "expected_start": "2026-10-20",
              "id": "d7e8f9a0-b1c2-4d3e-8f4a-5b6c7d8e9fa0",
              "name": "Cutting",
              "sort_order": 1,
              "status": {
                "color": "#2f6fb0",
                "id": "9c1d2e3f-4a5b-4c6d-8e7f-0a1b2c3d4e5f",
                "is_complete": false,
                "name": "Cutting"
              }
            }
          ],
          "status": {
            "color": "#2f6fb0",
            "id": "9c1d2e3f-4a5b-4c6d-8e7f-0a1b2c3d4e5f",
            "is_complete": false,
            "name": "Cutting"
          },
          "template": {
            "id": "b5c6d7e8-f9a0-4b1c-8d2e-3f4a5b6c7d8e",
            "name": "Frameless boxes"
          },
          "type": {
            "id": "a4b5c6d7-e8f9-4a0b-9c1d-2e3f4a5b6c7d",
            "name": "Production"
          },
          "updated_at": "2026-10-05T09:12:44Z"
        },
        "properties": {
          "assigned_user_ids": {
            "items": {
              "format": "uuid",
              "type": "string"
            },
            "title": "Assigned User Ids",
            "type": "array"
          },
          "completed_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When it last entered a completed status.",
            "title": "Completed At"
          },
          "completion_pct": {
            "default": 0.0,
            "description": "How much of the current step's checklist is done, 0 to 100.",
            "title": "Completion Pct",
            "type": "number"
          },
          "created_at": {
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "due_date": {
            "anyOf": [
              {
                "format": "date",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Due Date"
          },
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "job": {
            "$ref": "#/components/schemas/WorkOrderJobRef"
          },
          "name": {
            "title": "Name",
            "type": "string"
          },
          "priority": {
            "default": 0,
            "title": "Priority",
            "type": "integer"
          },
          "reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The work order number people use, e.g. W318.",
            "title": "Reference"
          },
          "sections": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/WorkOrderSectionOut"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Its steps in order. Present on a single work order, or with include=sections.",
            "title": "Sections"
          },
          "status": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/app__api__v1__work_orders__schema__WorkOrderStatusOut"
              },
              {
                "type": "null"
              }
            ],
            "description": "The step it is at now."
          },
          "template": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Ref"
              },
              {
                "type": "null"
              }
            ],
            "description": "The template its steps came from."
          },
          "type": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Ref"
              },
              {
                "type": "null"
              }
            ],
            "description": "Prep, Production, Install or the account's own; from GET /v1/meta/work-order-types."
          },
          "updated_at": {
            "format": "date-time",
            "title": "Updated At",
            "type": "string"
          }
        },
        "required": [
          "id",
          "name",
          "job",
          "created_at",
          "updated_at"
        ],
        "title": "WorkOrderOut",
        "type": "object"
      },
      "WorkOrderPage": {
        "example": {
          "data": [
            {
              "assigned_user_ids": [
                "e1d2c3b4-a596-4877-8695-a4b3c2d1e0f9"
              ],
              "completion_pct": 40.0,
              "created_at": "2026-10-01T15:04:00Z",
              "due_date": "2026-11-02",
              "id": "6e2b9a14-3c5d-4f70-8a91-b2c3d4e5f607",
              "job": {
                "id": "3f9a1c77-5e3b-4a02-9d8e-2c7b6a1f0e4d",
                "name": "Whitfield kitchen remodel",
                "reference": "J1042"
              },
              "name": "Kitchen boxes",
              "priority": 2,
              "reference": "W318",
              "status": {
                "color": "#2f6fb0",
                "id": "9c1d2e3f-4a5b-4c6d-8e7f-0a1b2c3d4e5f",
                "is_complete": false,
                "name": "Cutting"
              },
              "template": {
                "id": "b5c6d7e8-f9a0-4b1c-8d2e-3f4a5b6c7d8e",
                "name": "Frameless boxes"
              },
              "type": {
                "id": "a4b5c6d7-e8f9-4a0b-9c1d-2e3f4a5b6c7d",
                "name": "Production"
              },
              "updated_at": "2026-10-05T09:12:44Z"
            }
          ],
          "has_more": true,
          "next_cursor": "eyJ2IjoiMjAyNi0xMC0wMVQxNTowNDowMCswMDowMCJ9.4c1e0a9b7d2f"
        },
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/WorkOrderOut"
            },
            "title": "Data",
            "type": "array"
          },
          "has_more": {
            "default": false,
            "title": "Has More",
            "type": "boolean"
          },
          "next_cursor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Pass as `cursor` to get the next page. Null at the end.",
            "title": "Next Cursor"
          }
        },
        "title": "WorkOrderPage",
        "type": "object"
      },
      "WorkOrderSectionOut": {
        "description": "One step of the work order. Read only: the checklist inside a step is\nfilled in the app and on the shop floor.",
        "properties": {
          "department_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The department doing this step, from GET /v1/meta/departments.",
            "title": "Department Id"
          },
          "expected_end": {
            "anyOf": [
              {
                "format": "date",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Expected End"
          },
          "expected_start": {
            "anyOf": [
              {
                "format": "date",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Expected Start"
          },
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "name": {
            "title": "Name",
            "type": "string"
          },
          "sort_order": {
            "default": 0,
            "title": "Sort Order",
            "type": "integer"
          },
          "status": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/app__api__v1__work_orders__schema__WorkOrderStatusOut"
              },
              {
                "type": "null"
              }
            ],
            "description": "The status this step stands for. Its id is a valid status_id for a move."
          }
        },
        "required": [
          "id",
          "name"
        ],
        "title": "WorkOrderSectionOut",
        "type": "object"
      },
      "WorkOrderStatusIn": {
        "example": {
          "status_id": "9c1d2e3f-4a5b-4c6d-8e7f-0a1b2c3d4e5f"
        },
        "properties": {
          "status_id": {
            "description": "One of the work order's own steps: the status id on one of its sections.",
            "format": "uuid",
            "title": "Status Id",
            "type": "string"
          }
        },
        "required": [
          "status_id"
        ],
        "title": "WorkOrderStatusIn",
        "type": "object"
      },
      "WorkOrderTypeOut": {
        "description": "A kind of work order and the statuses it moves through.",
        "example": {
          "color": "#7a4b1e",
          "id": "3c9d1e2f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
          "name": "Production",
          "statuses": [
            {
              "color": "#c47a2c",
              "id": "9f8e7d6c-5b4a-4392-8170-6f5e4d3c2b1a",
              "is_complete": false,
              "is_default": true,
              "name": "Cutting",
              "order": 1
            },
            {
              "color": "#1a661a",
              "id": "1a2b3c4d-5e6f-4071-8293-a4b5c6d7e8f9",
              "is_complete": true,
              "is_default": false,
              "name": "Done",
              "order": 5
            }
          ]
        },
        "properties": {
          "color": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Color"
          },
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description"
          },
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "name": {
            "title": "Name",
            "type": "string"
          },
          "statuses": {
            "items": {
              "$ref": "#/components/schemas/app__api__v1__meta__schema__WorkOrderStatusOut"
            },
            "title": "Statuses",
            "type": "array"
          }
        },
        "required": [
          "id",
          "name"
        ],
        "title": "WorkOrderTypeOut",
        "type": "object"
      },
      "WorkOrderUpdateIn": {
        "description": "Only the fields you send change. The status moves through its own\ncall; send `due_date: null` to clear the date.",
        "example": {
          "due_date": "2026-11-09",
          "name": "Kitchen uppers",
          "priority": 3
        },
        "properties": {
          "assigned_user_ids": {
            "anyOf": [
              {
                "items": {
                  "format": "uuid",
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Assigned User Ids"
          },
          "due_date": {
            "anyOf": [
              {
                "format": "date",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Due Date"
          },
          "name": {
            "anyOf": [
              {
                "maxLength": 255,
                "minLength": 1,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name"
          },
          "priority": {
            "anyOf": [
              {
                "maximum": 1000.0,
                "minimum": 0.0,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Priority"
          }
        },
        "title": "WorkOrderUpdateIn",
        "type": "object"
      },
      "app__api__v1__meta__schema__UnitOut": {
        "example": {
          "abbreviation": "lf",
          "id": "c3d4e5f6-a7b8-4901-8cde-f01234567890",
          "name": "Linear foot"
        },
        "properties": {
          "abbreviation": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Abbreviation"
          },
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "name": {
            "title": "Name",
            "type": "string"
          }
        },
        "required": [
          "id",
          "name"
        ],
        "title": "UnitOut",
        "type": "object"
      },
      "app__api__v1__meta__schema__WorkOrderStatusOut": {
        "properties": {
          "color": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Color"
          },
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "is_complete": {
            "default": false,
            "title": "Is Complete",
            "type": "boolean"
          },
          "is_default": {
            "default": false,
            "title": "Is Default",
            "type": "boolean"
          },
          "name": {
            "title": "Name",
            "type": "string"
          },
          "order": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Order"
          }
        },
        "required": [
          "id",
          "name"
        ],
        "title": "WorkOrderStatusOut",
        "type": "object"
      },
      "app__api__v1__products__schema__UnitOut": {
        "properties": {
          "abbreviation": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Abbreviation"
          },
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "name": {
            "title": "Name",
            "type": "string"
          }
        },
        "required": [
          "id",
          "name"
        ],
        "title": "UnitOut",
        "type": "object"
      },
      "app__api__v1__work_orders__schema__WorkOrderStatusOut": {
        "example": {
          "color": "#2f6fb0",
          "id": "9c1d2e3f-4a5b-4c6d-8e7f-0a1b2c3d4e5f",
          "is_complete": false,
          "name": "Cutting"
        },
        "properties": {
          "color": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Color"
          },
          "id": {
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "is_complete": {
            "default": false,
            "title": "Is Complete",
            "type": "boolean"
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name"
          }
        },
        "required": [
          "id"
        ],
        "title": "WorkOrderStatusOut",
        "type": "object"
      }
    },
    "securitySchemes": {
      "API key": {
        "description": "Your API key, e.g. `wsk_live_7f3a2b91.xxxxx`. Created by an admin in Settings, Integrations, API keys. Keep it on your server: anyone who has it can act as the user it is assigned to. Sandbox keys start `wsk_test_` and work only against the sandbox base URL.",
        "in": "header",
        "name": "X-Api-Key",
        "type": "apiKey"
      },
      "Account id": {
        "description": "The account id (a UUID) the key belongs to, given to you alongside the key. Required with X-Api-Key, checked against the key, so pasting one account's key into another account's integration fails immediately rather than filing their records in the wrong place. Not needed with a Bearer credential.",
        "in": "header",
        "name": "X-Tenant-Id",
        "type": "apiKey"
      },
      "Bearer": {
        "description": "`Bearer wsk_live_...` (an API key, for agents and the MCP server) or `Bearer wsa_...` (an OAuth access token from a connected app).",
        "in": "header",
        "name": "Authorization",
        "type": "apiKey"
      }
    }
  },
  "info": {
    "contact": {
      "name": "WoodSystems developer docs",
      "url": "https://developers.woodsystems.com"
    },
    "description": "\nRead and write a WoodSystems account from your own systems: jobs and leads,\ncontacts, tasks, calendar, estimates, invoices, files, work orders,\nmaterials, purchasing and products.\n\n### Getting started\n\n1. An admin creates an API key in **Settings, Integrations, API keys**, chooses\n   which user it acts as and what it may do (its scopes), and gives you the\n   key and the account id.\n2. Send both on every request:\n\n   | Header | Value |\n   |---|---|\n   | `X-Api-Key` | the key, e.g. `wsk_live_7f3a2b91.xxxxx` |\n   | `X-Tenant-Id` | the account id (a UUID) |\n   | `Idempotency-Key` | a unique string per write (required on POST) |\n\n   Or send `Authorization: Bearer wsk_live_...` and skip `X-Tenant-Id`.\n3. Call `GET /v1/account` to check the key works and see who it acts as.\n4. Look up ids under `GET /v1/meta/*` (statuses, types, fields), then make\n   your first call.\n\n### Who a call acts as\n\nEvery call acts as the user the key is assigned to, with that user's current\nrole. Money fields are blank for roles that cannot see costs in the app; a\nwrite the role may not make in the app is refused here too\n(`ERR_ROLE_REQUIRED`). If that user is deactivated the key stops working\n(`ERR_ACTOR_INACTIVE`) until an admin assigns it to someone else.\n\n### Idempotency\n\nEvery `POST` needs an `Idempotency-Key`: any unique string per submission. If\nthe same key arrives twice with the same body you get the first response\nback (`Idempotent-Replayed: true`) rather than a second record. The same key\nwith a different body is refused (`ERR_IDEMPOTENCY_MISMATCH`). Keys are\nremembered for 24 hours.\n\n### Pagination and sync\n\nLists return `{\"data\": [...], \"next_cursor\": ..., \"has_more\": ...}`. Pass\n`cursor` to continue; cursors are opaque. Lists of records that change\n(jobs, contacts, tasks, calendar events, estimates, invoices, work orders,\npurchase orders, vendors, products, stock items) take `updated_since`\n(RFC 3339) to fetch what changed, oldest first, which is how to keep another\nsystem in step without re-reading everything. Each list's parameters say\nwhether it does.\n\n### Rate limits and usage\n\nEvery response carries `X-RateLimit-Limit`, `X-RateLimit-Remaining` and\n`X-RateLimit-Reset`. Over the limit you get `429` with `Retry-After`. Calls\ncount toward the account's monthly included quota (`X-Quota-Limit`,\n`X-Quota-Used`); past it, calls are billed per 1,000 up to the account's cap.\n\n### Errors\n\nEvery error is `{\"detail\": \"a sentence\", \"code\": \"ERR_...\", \"request_id\": \"...\"}`.\nBranch on `code`, show `detail`, quote `request_id` to support.\n\n### Money and dates\n\nMoney is a decimal string in major units (`\"1234.50\"`) with a `currency` on\nthe document. Timestamps are RFC 3339 UTC (`2026-10-06T14:22:05.412Z`);\ndates are `YYYY-MM-DD`.\n\n### Versioning\n\nEverything is under `/v1`. Changes are additive: new optional fields and new\nendpoints may appear, so parse leniently and ignore what you do not\nrecognise. Nothing is removed from `/v1`; a change that cannot be made that\nway becomes `/v2`, and `/v1` keeps working for at least a year after.\n",
    "title": "WoodSystems API",
    "version": "2026-10-06",
    "x-api-version": "2026-10-06",
    "x-error-catalog": [
      {
        "code": "ERR_TENANT_HEADER",
        "fix": "Send the account id given with the key, or use a Bearer credential, which does not need it.",
        "status": 400,
        "when": "X-Tenant-Id is missing or not a UUID."
      },
      {
        "code": "ERR_ACTOR_INACTIVE",
        "fix": "An admin assigns the key to another user in Settings, Integrations.",
        "status": 401,
        "when": "The user this credential acts as is no longer active."
      },
      {
        "code": "ERR_AUTH_INVALID_KEY",
        "fix": "Check the value was copied whole from Settings, Integrations.",
        "status": 401,
        "when": "The key or token is malformed, unknown or wrong."
      },
      {
        "code": "ERR_AUTH_KEY_REVOKED",
        "fix": "Create a new key in Settings, Integrations.",
        "status": 401,
        "when": "The key was revoked or switched off."
      },
      {
        "code": "ERR_AUTH_MISSING_KEY",
        "fix": "Send X-Api-Key or Authorization: Bearer.",
        "status": 401,
        "when": "No credential was sent."
      },
      {
        "code": "ERR_WRONG_ENVIRONMENT",
        "fix": "Use the base URL that matches the key: api.woodsystems.com for wsk_live_, api-sandbox.woodsystems.com for wsk_test_.",
        "status": 401,
        "when": "A sandbox key was sent to the live API, or a live key to the sandbox."
      },
      {
        "code": "ERR_QUOTA_EXCEEDED",
        "fix": "Add a payment method or raise the cap under Settings, Billing.",
        "status": 402,
        "when": "The month's calls are used up and no more can be billed."
      },
      {
        "code": "ERR_ACCOUNT_SUSPENDED",
        "fix": "The account owner settles billing under Settings, Billing.",
        "status": 403,
        "when": "The account is suspended."
      },
      {
        "code": "ERR_FORBIDDEN",
        "fix": "Read `detail`.",
        "status": 403,
        "when": "The account service refused the call."
      },
      {
        "code": "ERR_NOT_ENTITLED",
        "fix": "The account owner adds API & Integrations under Settings, Billing.",
        "status": 403,
        "when": "The account does not include the API."
      },
      {
        "code": "ERR_OAUTH_NOT_ALLOWED",
        "fix": "Use the WoodSystems web app, or an API key for this call.",
        "status": 403,
        "when": "Connected apps cannot do this."
      },
      {
        "code": "ERR_ROLE_REQUIRED",
        "fix": "Ask an admin to raise their role, or assign the key to a user with the role.",
        "status": 403,
        "when": "The user the credential acts as has a role below what this call needs."
      },
      {
        "code": "ERR_SANDBOX_ONLY",
        "fix": "Use the sandbox base URL.",
        "status": 403,
        "when": "This call exists only in the sandbox."
      },
      {
        "code": "ERR_SCOPE_MISSING",
        "fix": "Add the named scope to the key, or reconnect the app with it.",
        "status": 403,
        "when": "The credential does not hold the permission this call needs."
      },
      {
        "code": "ERR_TENANT_MISMATCH",
        "fix": "Check that the key and the account id came from the same place.",
        "status": 403,
        "when": "The key belongs to a different account than X-Tenant-Id names."
      },
      {
        "code": "ERR_NOT_FOUND",
        "fix": "Check the id; records of other accounts are never visible.",
        "status": 404,
        "when": "No such record in this account."
      },
      {
        "code": "ERR_CONFLICT",
        "fix": "Read the record again and retry.",
        "status": 409,
        "when": "The change conflicts with the record's current state."
      },
      {
        "code": "ERR_DELETE_BLOCKED",
        "fix": "Read `detail` for what depends on it.",
        "status": 409,
        "when": "The record cannot be deleted while other records depend on it."
      },
      {
        "code": "ERR_FEATURE_OFF",
        "fix": "Switch it on under Company Config.",
        "status": 409,
        "when": "The account has this area switched off."
      },
      {
        "code": "ERR_IDEMPOTENCY_IN_PROGRESS",
        "fix": "Wait and retry; or retry with a new key after checking whether the record exists.",
        "status": 409,
        "when": "A call with this Idempotency-Key is still running or never finished."
      },
      {
        "code": "ERR_LOCKED",
        "fix": "Change it in the web app, where the lock can be lifted.",
        "status": 409,
        "when": "The record is locked: a sent or signed document, a payroll-locked day, a scheduled event."
      },
      {
        "code": "ERR_NO_MAILBOX",
        "fix": "That user connects Gmail or Outlook under Profile settings, Personal Inbox, Send email as me.",
        "status": 409,
        "when": "The user the credential acts as has no connected mailbox to send from."
      },
      {
        "code": "ERR_OVER_RECEIPT",
        "fix": "Receive at most the outstanding quantity named in `detail`.",
        "status": 409,
        "when": "More was received than is still outstanding on the purchase order line."
      },
      {
        "code": "ERR_IDEMPOTENCY_MISMATCH",
        "fix": "Use a new Idempotency-Key for a new request.",
        "status": 422,
        "when": "This Idempotency-Key was used with a different request body."
      },
      {
        "code": "ERR_IDEMPOTENCY_REQUIRED",
        "fix": "Send a unique string per submission, such as a UUID.",
        "status": 422,
        "when": "This write needs an Idempotency-Key header."
      },
      {
        "code": "ERR_VALIDATION",
        "fix": "Read `errors` for each field.",
        "status": 422,
        "when": "The request body or query is not valid."
      },
      {
        "code": "ERR_RATE_LIMITED",
        "fix": "Wait for Retry-After seconds; read X-RateLimit-Remaining.",
        "status": 429,
        "when": "Too many calls in a short time."
      },
      {
        "code": "ERR_INTERNAL",
        "fix": "Quote request_id to support.",
        "status": 500,
        "when": "Something failed on our side."
      },
      {
        "code": "ERR_SEND_FAILED",
        "fix": "Read `detail` for the provider's reason; reconnect the mailbox if it says so.",
        "status": 502,
        "when": "The mail provider refused or failed the send."
      },
      {
        "code": "ERR_UPSTREAM",
        "fix": "Retry with backoff; quote request_id to support if it persists.",
        "status": 502,
        "when": "The account service could not complete the call."
      },
      {
        "code": "ERR_LIMITER_UNAVAILABLE",
        "fix": "Retry after Retry-After seconds; quote request_id to support if it persists.",
        "status": 503,
        "when": "The rate limiter could not record the call, so it was not made."
      },
      {
        "code": "ERR_UPSTREAM_TIMEOUT",
        "fix": "Retry with backoff.",
        "status": 504,
        "when": "The account service took too long."
      }
    ]
  },
  "openapi": "3.1.0",
  "paths": {
    "/v1/account": {
      "get": {
        "description": "Confirm a credential works and see what it is allowed to do.\n\nCall this once when you set an integration up. It is the cheapest way to\nfind out that a key is valid, that it is pointed at the right account, and\nthat it holds the permissions the rest of your integration needs - before\nyou discover any of that from a failed call at 3am.",
        "operationId": "account.get",
        "parameters": [
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AccountOut"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "Check your credentials",
        "tags": [
          "Account"
        ],
        "x-scopes": [
          "meta:read"
        ]
      }
    },
    "/v1/account/usage": {
      "get": {
        "description": "Calls this month against the included amount, the limits in force, and\nthe last 31 days day by day. Needs a key acting as an admin or owner.\n\nWebhook first deliveries count as calls; retries do not. Calls made by\nthe MCP server are API calls and are also shown on their own.",
        "operationId": "account.usage",
        "parameters": [
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UsageOut"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "See this account's API usage",
        "tags": [
          "Account"
        ],
        "x-admin": true,
        "x-scopes": [
          "usage:read"
        ]
      }
    },
    "/v1/calendar/events": {
      "get": {
        "description": "Every event that overlaps the window, earliest first.\n\n`start` and `end` are required and the window can be at most 92 days, so\nto sync a calendar, walk it a window at a time. The list is not paged.\n\nA user with a production role sees what they see in the app: their\ndepartments' and teams' events and their own.",
        "operationId": "calendar.list",
        "parameters": [
          {
            "description": "Window start, RFC 3339. Without an offset it is read as UTC.",
            "in": "query",
            "name": "start",
            "required": true,
            "schema": {
              "description": "Window start, RFC 3339. Without an offset it is read as UTC.",
              "format": "date-time",
              "title": "Start",
              "type": "string"
            }
          },
          {
            "description": "Window end. At most 92 days after start.",
            "in": "query",
            "name": "end",
            "required": true,
            "schema": {
              "description": "Window end. At most 92 days after start.",
              "format": "date-time",
              "title": "End",
              "type": "string"
            }
          },
          {
            "description": "Only this job's events.",
            "in": "query",
            "name": "job_id",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "format": "uuid",
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only this job's events.",
              "title": "Job Id"
            }
          },
          {
            "description": "Only events this person is on, from GET /v1/meta/users.",
            "in": "query",
            "name": "user_id",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "format": "uuid",
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only events this person is on, from GET /v1/meta/users.",
              "title": "User Id"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/EventOut"
                  },
                  "title": "Response Calendar.List",
                  "type": "array"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "List events in a date range",
        "tags": [
          "Calendar"
        ],
        "x-scopes": [
          "calendar:read"
        ]
      },
      "post": {
        "description": "Book an event on the calendar.\n\nAssign it to departments or teams; the people on it are their members,\nand each of them is notified the way the app notifies them. A timed event\nhas to fall inside the account's office hours (an all-day or multi-day\nevent does not). Needs an office role or above.",
        "operationId": "calendar.create",
        "parameters": [
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EventCreateIn"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EventOut"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "The job, department or team is not in this account (ERR_NOT_FOUND).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "Create an event",
        "tags": [
          "Calendar"
        ],
        "x-scopes": [
          "calendar:write"
        ]
      }
    },
    "/v1/calendar/events/{event_id}": {
      "delete": {
        "description": "Remove an event from the calendar.\n\nAn event the job's timeline made is not made again on that job once it is\ndeleted. A tentative event (part of a rough plan) cannot be deleted\n(ERR_LOCKED). Needs an office role or above.",
        "operationId": "calendar.delete",
        "parameters": [
          {
            "in": "path",
            "name": "event_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Event Id",
              "type": "string"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "No such event in this account (ERR_NOT_FOUND).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "The event is part of a job's rough plan and cannot be changed this way (ERR_LOCKED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "Delete an event",
        "tags": [
          "Calendar"
        ],
        "x-scopes": [
          "calendar:write"
        ]
      },
      "get": {
        "description": "One event, with its job, departments and the people on it.",
        "operationId": "calendar.get",
        "parameters": [
          {
            "in": "path",
            "name": "event_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Event Id",
              "type": "string"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EventOut"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "No such event in this account (ERR_NOT_FOUND).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "Get an event",
        "tags": [
          "Calendar"
        ],
        "x-scopes": [
          "calendar:read"
        ]
      },
      "patch": {
        "description": "Move an event, or change its title, description, job, departments or\nteams. Only the fields you send change.\n\nAn event with `tentative: true` belongs to a job whose dates are still a\nrough plan: it can be moved and its description changed, and anything\nelse is refused with ERR_LOCKED until the job's dates are confirmed in\nthe app. Moving an event the job's timeline made (`from_timeline: true`)\nis allowed; from then on the job's dates no longer move it. Needs an\noffice role or above.",
        "operationId": "calendar.update",
        "parameters": [
          {
            "in": "path",
            "name": "event_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Event Id",
              "type": "string"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EventUpdateIn"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EventOut"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "No such event in this account (ERR_NOT_FOUND).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "The event is part of a job's rough plan and cannot be changed this way (ERR_LOCKED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "Update an event",
        "tags": [
          "Calendar"
        ],
        "x-scopes": [
          "calendar:write"
        ]
      }
    },
    "/v1/contacts": {
      "get": {
        "description": "Everyone in the account's address book: customers, contractors and\nanybody else who has been put on a job.\n\nNewest first by default. With `updated_since`, you get every contact\ncreated or changed since then, oldest first, which is the order to use\nwhen copying contacts into another system. Page with `cursor`.\n\nA phone search ignores formatting, so `(512) 555-0147` finds a number\nsaved as `5125550147`.",
        "operationId": "contacts.list",
        "parameters": [
          {
            "description": "Search first name, last name, full name, email and phone number.",
            "in": "query",
            "name": "q",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "maxLength": 200,
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Search first name, last name, full name, email and phone number.",
              "title": "Q"
            }
          },
          {
            "description": "Only contacts changed at or after this time, oldest first. How to keep another system in step.",
            "in": "query",
            "name": "updated_since",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "format": "date-time",
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only contacts changed at or after this time, oldest first. How to keep another system in step.",
              "title": "Updated Since"
            }
          },
          {
            "description": "From the previous page's next_cursor.",
            "in": "query",
            "name": "cursor",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "From the previous page's next_cursor.",
              "title": "Cursor"
            }
          },
          {
            "description": "Page size, 1 to 200. Default 50.",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "maximum": 200,
                  "minimum": 1,
                  "type": "integer"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Page size, 1 to 200. Default 50.",
              "title": "Limit"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContactPage"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "List contacts",
        "tags": [
          "Contacts"
        ],
        "x-scopes": [
          "contacts:read"
        ]
      }
    },
    "/v1/contacts/{contact_id}": {
      "get": {
        "description": "One contact, with the jobs they are on.",
        "operationId": "contacts.get",
        "parameters": [
          {
            "in": "path",
            "name": "contact_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Contact Id",
              "type": "string"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContactOut"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "No such contact in this account (ERR_NOT_FOUND).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "Get a contact",
        "tags": [
          "Contacts"
        ],
        "x-scopes": [
          "contacts:read"
        ]
      },
      "patch": {
        "description": "Change a contact's name, email or phone number. Only the fields you\nsend change; send an empty string to clear email or phone_number.\n\nThe change shows everywhere the person appears, on every job they are\non. Incoming texts and calls are matched to contacts by phone number, so\nkeep numbers accurate. Needs an office role or above.",
        "operationId": "contacts.update",
        "parameters": [
          {
            "in": "path",
            "name": "contact_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Contact Id",
              "type": "string"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ContactUpdateIn"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContactOut"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "No such contact in this account (ERR_NOT_FOUND).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "Update a contact",
        "tags": [
          "Contacts"
        ],
        "x-scopes": [
          "contacts:write"
        ]
      }
    },
    "/v1/custom-fields": {
      "get": {
        "description": "The custom fields this account has set up on jobs.\n\nUse it to build your form and to get the `field_id` values you send back in\n`custom_field_values`. Only enabled fields are listed - anything missing from\nthis list would be rejected on the way in.\n\nAccounts change their fields, so read this when your integration starts\nrather than hard-coding ids from the day you built it.",
        "operationId": "meta.customFields",
        "parameters": [
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/CustomFieldOut"
                  },
                  "title": "Response Meta.Customfields",
                  "type": "array"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "List the account's job fields",
        "tags": [
          "Meta"
        ],
        "x-scopes": [
          "meta:read"
        ]
      }
    },
    "/v1/estimates": {
      "get": {
        "description": "Estimates newest first, or, with `updated_since`, everything changed\nsince then, oldest first. Page with `cursor`.\n\nNeeds an office role or above: estimates are money documents.",
        "operationId": "estimates.list",
        "parameters": [
          {
            "description": "Only this job's estimates.",
            "in": "query",
            "name": "job_id",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "format": "uuid",
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only this job's estimates.",
              "title": "Job Id"
            }
          },
          {
            "description": "Only estimates in this status.",
            "in": "query",
            "name": "status_id",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "format": "uuid",
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only estimates in this status.",
              "title": "Status Id"
            }
          },
          {
            "description": "Only estimates changed at or after this time, oldest first. How to keep another system in step.",
            "in": "query",
            "name": "updated_since",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "format": "date-time",
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only estimates changed at or after this time, oldest first. How to keep another system in step.",
              "title": "Updated Since"
            }
          },
          {
            "description": "From the previous page's next_cursor.",
            "in": "query",
            "name": "cursor",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "From the previous page's next_cursor.",
              "title": "Cursor"
            }
          },
          {
            "description": "Page size, 1 to 200. Default 50.",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "maximum": 200,
                  "minimum": 1,
                  "type": "integer"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Page size, 1 to 200. Default 50.",
              "title": "Limit"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EstimatePage"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "List estimates",
        "tags": [
          "Estimates"
        ],
        "x-scopes": [
          "estimates:read"
        ]
      },
      "post": {
        "description": "Start a draft estimate on a job. Add sections, then lines, to price it.\n\nIt starts in the account's default status (Draft) unless you name another\nthat does not lock editing. The account's default deposit applies unless\nyou send `deposit_amount`. Needs an office role or above.",
        "operationId": "estimates.create",
        "parameters": [
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EstimateCreateIn"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EstimateOut"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "No such job or status in this account (ERR_NOT_FOUND).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "The job already has an estimate and the account allows one per job (ERR_CONFLICT), or the job is in production (ERR_LOCKED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "Create a draft estimate",
        "tags": [
          "Estimates"
        ],
        "x-scopes": [
          "estimates:write"
        ]
      }
    },
    "/v1/estimates/{estimate_id}": {
      "get": {
        "description": "One estimate. Add `include=sections,lines` for its contents: sections in\norder, and every line with the section it sits in.",
        "operationId": "estimates.get",
        "parameters": [
          {
            "in": "path",
            "name": "estimate_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Estimate Id",
              "type": "string"
            }
          },
          {
            "description": "Comma separated: sections, lines.",
            "in": "query",
            "name": "include",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Comma separated: sections, lines.",
              "title": "Include"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EstimateOut"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "No such estimate in this account (ERR_NOT_FOUND).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "Get an estimate",
        "tags": [
          "Estimates"
        ],
        "x-scopes": [
          "estimates:read"
        ]
      },
      "patch": {
        "description": "Change a draft's name, dates, deposit, tax rate, notes, terms or status.\nOnly the fields you send change.\n\nA sent or signed estimate is refused with ERR_LOCKED: it is changed in the\nweb app, where the lock can be lifted.",
        "operationId": "estimates.update",
        "parameters": [
          {
            "in": "path",
            "name": "estimate_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Estimate Id",
              "type": "string"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EstimateUpdateIn"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EstimateOut"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "No such estimate, section or line in this account (ERR_NOT_FOUND).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "The estimate is sent or signed and cannot be changed here (ERR_LOCKED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "Update a draft estimate",
        "tags": [
          "Estimates"
        ],
        "x-scopes": [
          "estimates:write"
        ]
      }
    },
    "/v1/estimates/{estimate_id}/lines/{line_id}": {
      "patch": {
        "description": "Change a line on a draft estimate. Only the fields you send change; a\ntyped `unit_price` stays put when the catalog's price moves.",
        "operationId": "estimates.updateLine",
        "parameters": [
          {
            "in": "path",
            "name": "estimate_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Estimate Id",
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "line_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Line Id",
              "type": "string"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LineUpdateIn"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LineOut"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "No such estimate, section or line in this account (ERR_NOT_FOUND).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "The estimate is sent or signed and cannot be changed here (ERR_LOCKED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "Update a line",
        "tags": [
          "Estimates"
        ],
        "x-scopes": [
          "estimates:write"
        ]
      }
    },
    "/v1/estimates/{estimate_id}/sections": {
      "post": {
        "description": "Add a section (a room, an area, a phase) at the end of a draft estimate.\nLines are added to a section.",
        "operationId": "estimates.addSection",
        "parameters": [
          {
            "in": "path",
            "name": "estimate_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Estimate Id",
              "type": "string"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SectionCreateIn"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SectionOut"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "No such estimate, section or line in this account (ERR_NOT_FOUND).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "The estimate is sent or signed and cannot be changed here (ERR_LOCKED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "Add a section",
        "tags": [
          "Estimates"
        ],
        "x-scopes": [
          "estimates:write"
        ]
      }
    },
    "/v1/estimates/{estimate_id}/sections/{section_id}/lines": {
      "post": {
        "description": "Add a priced line at the end of a section. The estimate's totals are\nrecalculated; read the estimate again for them.\n\nWith `product_id` the catalog prices the line unless you send\n`unit_price`. Without one, `unit_price` is required.",
        "operationId": "estimates.addLine",
        "parameters": [
          {
            "in": "path",
            "name": "estimate_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Estimate Id",
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "section_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Section Id",
              "type": "string"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LineCreateIn"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LineOut"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "No such estimate, section or line in this account (ERR_NOT_FOUND).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "The estimate is sent or signed and cannot be changed here (ERR_LOCKED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "Add a line",
        "tags": [
          "Estimates"
        ],
        "x-scopes": [
          "estimates:write"
        ]
      }
    },
    "/v1/estimates/{estimate_id}/send": {
      "post": {
        "description": "Email each contact their own link to the estimate, from the mailbox of\nthe user the credential acts as.\n\nNeeds `comms:send` as well as `estimates:write`, and a manager role or\nabove. The acting user must have Gmail or Outlook connected in the app;\nwithout it nothing is sent (ERR_NO_MAILBOX). Each recipient gets their own\nemail and their own conversation, so replies land in the right thread.\nSend an `Idempotency-Key`: a retried send would otherwise email twice.",
        "operationId": "estimates.send",
        "parameters": [
          {
            "in": "path",
            "name": "estimate_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Estimate Id",
              "type": "string"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EstimateSendIn"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SendResult"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "No such estimate or contact in this account (ERR_NOT_FOUND).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "No connected mailbox to send from (ERR_NO_MAILBOX), or it sent to nobody (ERR_CONFLICT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "Email an estimate to contacts",
        "tags": [
          "Estimates"
        ],
        "x-scopes": [
          "estimates:write"
        ]
      }
    },
    "/v1/files/complete": {
      "post": {
        "description": "Put an uploaded file on the job. Step 3 of 3.\n\nCall it after the `PUT` to `upload_url` succeeded. The file is checked in\nstorage and appears on the job's Files tab. If the bytes are not there\nyet this answers ERR_CONFLICT and you can call it again; a file over\n100 MB is removed and refused. Calling it again with the same token\nreturns the same file rather than adding a second.",
        "operationId": "files.complete",
        "parameters": [
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UploadCompleteIn"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FileOut"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "The bytes have not arrived in storage yet (ERR_CONFLICT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "Finish an upload",
        "tags": [
          "Files"
        ],
        "x-scopes": [
          "files:write"
        ]
      }
    },
    "/v1/files/{file_id}": {
      "get": {
        "description": "One file, with a `download_url` that works for 24 hours.\n\nThe link needs no credential, so treat it like the file itself: fetch\nfrom it, do not store or share it. Ask again for a fresh one.",
        "operationId": "files.get",
        "parameters": [
          {
            "in": "path",
            "name": "file_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "File Id",
              "type": "string"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FileWithLinkOut"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "No such file in this account (ERR_NOT_FOUND).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "Get a file",
        "tags": [
          "Files"
        ],
        "x-scopes": [
          "files:read"
        ]
      }
    },
    "/v1/invoices": {
      "get": {
        "description": "Invoices newest first, or, with `updated_since`, everything changed\nsince then, oldest first. Page with `cursor`. A payment changes an\ninvoice's balance, so a sync on `updated_since` sees it.\n\nNeeds an office role or above.",
        "operationId": "invoices.list",
        "parameters": [
          {
            "description": "Only this job's invoices.",
            "in": "query",
            "name": "job_id",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "format": "uuid",
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only this job's invoices.",
              "title": "Job Id"
            }
          },
          {
            "description": "Only invoices made from this estimate.",
            "in": "query",
            "name": "estimate_id",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "format": "uuid",
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only invoices made from this estimate.",
              "title": "Estimate Id"
            }
          },
          {
            "description": "Only invoices in this status.",
            "in": "query",
            "name": "status_id",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "format": "uuid",
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only invoices in this status.",
              "title": "Status Id"
            }
          },
          {
            "description": "Only invoices changed at or after this time, oldest first. How to keep another system in step.",
            "in": "query",
            "name": "updated_since",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "format": "date-time",
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only invoices changed at or after this time, oldest first. How to keep another system in step.",
              "title": "Updated Since"
            }
          },
          {
            "description": "From the previous page's next_cursor.",
            "in": "query",
            "name": "cursor",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "From the previous page's next_cursor.",
              "title": "Cursor"
            }
          },
          {
            "description": "Page size, 1 to 200. Default 50.",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "maximum": 200,
                  "minimum": 1,
                  "type": "integer"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Page size, 1 to 200. Default 50.",
              "title": "Limit"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvoicePage"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "List invoices",
        "tags": [
          "Invoices"
        ],
        "x-scopes": [
          "invoices:read"
        ]
      },
      "post": {
        "description": "Start an invoice on a job with no lines; add sections and lines to it.\nTo bill an estimate, use `POST /v1/invoices/from-estimate/{estimate_id}`\ninstead, which copies its lines. Needs an office role or above.",
        "operationId": "invoices.create",
        "parameters": [
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InvoiceCreateIn"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvoiceOut"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "No such job in this account (ERR_NOT_FOUND).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "Create a blank invoice",
        "tags": [
          "Invoices"
        ],
        "x-scopes": [
          "invoices:write"
        ]
      }
    },
    "/v1/invoices/from-estimate/{estimate_id}": {
      "post": {
        "description": "Make an invoice from an estimate: its sections and lines are copied, and\n`amount_mode` decides how much of the total this invoice bills. A deposit\nis `percentage` or `amount`; the final bill is `remaining_balance`.\nNeeds an office role or above.",
        "operationId": "invoices.fromEstimate",
        "parameters": [
          {
            "in": "path",
            "name": "estimate_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Estimate Id",
              "type": "string"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InvoiceFromEstimateIn"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvoiceOut"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "No such estimate in this account (ERR_NOT_FOUND).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "Invoice an estimate",
        "tags": [
          "Invoices"
        ],
        "x-scopes": [
          "invoices:write"
        ]
      }
    },
    "/v1/invoices/{invoice_id}": {
      "get": {
        "description": "One invoice with its total, amount due and balance. Add\n`include=sections,lines` for its contents.",
        "operationId": "invoices.get",
        "parameters": [
          {
            "in": "path",
            "name": "invoice_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Invoice Id",
              "type": "string"
            }
          },
          {
            "description": "Comma separated: sections, lines.",
            "in": "query",
            "name": "include",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Comma separated: sections, lines.",
              "title": "Include"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvoiceOut"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "No such invoice in this account (ERR_NOT_FOUND).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "Get an invoice",
        "tags": [
          "Invoices"
        ],
        "x-scopes": [
          "invoices:read"
        ]
      },
      "patch": {
        "description": "Change an invoice's name, dates, tax rate, notes, terms or status. Only\nthe fields you send change. A paid or void invoice is refused with\nERR_LOCKED.",
        "operationId": "invoices.update",
        "parameters": [
          {
            "in": "path",
            "name": "invoice_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Invoice Id",
              "type": "string"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InvoiceUpdateIn"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvoiceOut"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "No such invoice, section or line in this account (ERR_NOT_FOUND).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "The invoice is in a status that locks editing, e.g. paid or void (ERR_LOCKED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "Update a draft invoice",
        "tags": [
          "Invoices"
        ],
        "x-scopes": [
          "invoices:write"
        ]
      }
    },
    "/v1/invoices/{invoice_id}/lines/{line_id}": {
      "patch": {
        "description": "Change a line on an invoice. Only the fields you send change.",
        "operationId": "invoices.updateLine",
        "parameters": [
          {
            "in": "path",
            "name": "invoice_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Invoice Id",
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "line_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Line Id",
              "type": "string"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LineUpdateIn"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LineOut"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "No such invoice, section or line in this account (ERR_NOT_FOUND).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "The invoice is in a status that locks editing, e.g. paid or void (ERR_LOCKED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "Update an invoice line",
        "tags": [
          "Invoices"
        ],
        "x-scopes": [
          "invoices:write"
        ]
      }
    },
    "/v1/invoices/{invoice_id}/payments": {
      "get": {
        "description": "Every payment recorded against or applied to this invoice, oldest\nfirst, each with `applied_amount`: what it pays on this invoice.",
        "operationId": "invoices.payments",
        "parameters": [
          {
            "in": "path",
            "name": "invoice_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Invoice Id",
              "type": "string"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/PaymentOut"
                  },
                  "title": "Response Invoices.Payments",
                  "type": "array"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "No such invoice in this account (ERR_NOT_FOUND).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "List an invoice's payments",
        "tags": [
          "Invoices"
        ],
        "x-scopes": [
          "invoices:read"
        ]
      }
    },
    "/v1/invoices/{invoice_id}/sections": {
      "post": {
        "description": "Add a section at the end of an invoice. Lines are added to a section.",
        "operationId": "invoices.addSection",
        "parameters": [
          {
            "in": "path",
            "name": "invoice_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Invoice Id",
              "type": "string"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SectionCreateIn"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SectionOut"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "No such invoice, section or line in this account (ERR_NOT_FOUND).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "The invoice is in a status that locks editing, e.g. paid or void (ERR_LOCKED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "Add a section to an invoice",
        "tags": [
          "Invoices"
        ],
        "x-scopes": [
          "invoices:write"
        ]
      }
    },
    "/v1/invoices/{invoice_id}/sections/{section_id}/lines": {
      "post": {
        "description": "Add a priced line at the end of a section. The invoice's total, amount\ndue and balance are recalculated; read the invoice again for them.",
        "operationId": "invoices.addLine",
        "parameters": [
          {
            "in": "path",
            "name": "invoice_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Invoice Id",
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "section_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Section Id",
              "type": "string"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InvoiceLineCreateIn"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LineOut"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "No such invoice, section or line in this account (ERR_NOT_FOUND).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "The invoice is in a status that locks editing, e.g. paid or void (ERR_LOCKED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "Add a line to an invoice",
        "tags": [
          "Invoices"
        ],
        "x-scopes": [
          "invoices:write"
        ]
      }
    },
    "/v1/invoices/{invoice_id}/send": {
      "post": {
        "description": "Email each contact their own link to the invoice, from the mailbox of\nthe user the credential acts as.\n\nNeeds `comms:send` as well as `invoices:write`, and a manager role or\nabove. Without a connected Gmail or Outlook mailbox nothing is sent\n(ERR_NO_MAILBOX). The API never creates a payment link: if the invoice\nalready shows one in the app, the email carries it. Send an\n`Idempotency-Key`: a retried send would otherwise email twice.",
        "operationId": "invoices.send",
        "parameters": [
          {
            "in": "path",
            "name": "invoice_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Invoice Id",
              "type": "string"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SendIn"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SendResult"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "No such invoice or contact in this account (ERR_NOT_FOUND).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "No connected mailbox to send from (ERR_NO_MAILBOX), or it sent to nobody (ERR_CONFLICT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "Email an invoice to contacts",
        "tags": [
          "Invoices"
        ],
        "x-scopes": [
          "invoices:write"
        ]
      }
    },
    "/v1/job-forms": {
      "get": {
        "description": "The job form templates this account uses.\n\nA job form is the structured intake the shop fills in per job - room by room\nfor a cabinet maker, unit by unit for a multi-family job. If you want your\nlead to arrive with that already partly filled in, read the form here and\nsend matching keys in `form.values` and `form.sections`.\n\n`is_default` marks the one the account uses when nobody chooses.",
        "operationId": "meta.jobForms",
        "parameters": [
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/FormSchemaOut"
                  },
                  "title": "Response Meta.Jobforms",
                  "type": "array"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "List the account's job forms",
        "tags": [
          "Meta"
        ],
        "x-scopes": [
          "meta:read"
        ]
      }
    },
    "/v1/job-forms/{form_id}": {
      "get": {
        "description": "One job form template and its fields.",
        "operationId": "meta.jobForm",
        "parameters": [
          {
            "in": "path",
            "name": "form_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Form Id",
              "type": "string"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FormSchemaOut"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "No such form on this account (ERR_NOT_FOUND).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "Get one job form",
        "tags": [
          "Meta"
        ],
        "x-scopes": [
          "meta:read"
        ]
      }
    },
    "/v1/jobs": {
      "get": {
        "description": "Jobs newest first, or, with `updated_since`, everything changed since\nthen, oldest first. Page with `cursor`.",
        "operationId": "jobs.list",
        "parameters": [
          {
            "description": "lead, opportunity or job; several separated by commas.",
            "in": "query",
            "name": "stage",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "lead, opportunity or job; several separated by commas.",
              "title": "Stage"
            }
          },
          {
            "description": "Only jobs in this main status or phase.",
            "in": "query",
            "name": "status_id",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "format": "uuid",
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only jobs in this main status or phase.",
              "title": "Status Id"
            }
          },
          {
            "description": "Search the name, job number and city.",
            "in": "query",
            "name": "q",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "maxLength": 200,
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Search the name, job number and city.",
              "title": "Q"
            }
          },
          {
            "description": "Only jobs changed at or after this time, oldest first. How to keep another system in step.",
            "in": "query",
            "name": "updated_since",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "format": "date-time",
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only jobs changed at or after this time, oldest first. How to keep another system in step.",
              "title": "Updated Since"
            }
          },
          {
            "description": "Comma separated: contacts, custom_fields.",
            "in": "query",
            "name": "include",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Comma separated: contacts, custom_fields.",
              "title": "Include"
            }
          },
          {
            "description": "From the previous page's next_cursor.",
            "in": "query",
            "name": "cursor",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "From the previous page's next_cursor.",
              "title": "Cursor"
            }
          },
          {
            "description": "Page size, 1 to 200. Default 50.",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "maximum": 200,
                  "minimum": 1,
                  "type": "integer"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Page size, 1 to 200. Default 50.",
              "title": "Limit"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobPage"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "List jobs",
        "tags": [
          "Jobs"
        ],
        "x-scopes": [
          "jobs:read"
        ]
      },
      "post": {
        "description": "Create a lead, opportunity or job, with new or existing contacts.\n\nIt lands in the pipeline at once and the office is told, the same as a\njob made in the app. Needs an office role or above.",
        "operationId": "jobs.create",
        "parameters": [
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/JobCreateIn"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobOut"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "Create a job",
        "tags": [
          "Jobs"
        ],
        "x-scopes": [
          "jobs:write"
        ]
      }
    },
    "/v1/jobs/{job_id}": {
      "get": {
        "description": "One job with its contacts and custom field values.",
        "operationId": "jobs.get",
        "parameters": [
          {
            "in": "path",
            "name": "job_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Job Id",
              "type": "string"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobOut"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "No such job in this account (ERR_NOT_FOUND).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "Get a job",
        "tags": [
          "Jobs"
        ],
        "x-scopes": [
          "jobs:read"
        ]
      },
      "patch": {
        "description": "Change a job's name, address, project manager or expected dates. Only\nthe fields you send change.",
        "operationId": "jobs.update",
        "parameters": [
          {
            "in": "path",
            "name": "job_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Job Id",
              "type": "string"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/JobUpdateIn"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobOut"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "No such job in this account (ERR_NOT_FOUND).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "Update a job",
        "tags": [
          "Jobs"
        ],
        "x-scopes": [
          "jobs:write"
        ]
      }
    },
    "/v1/jobs/{job_id}/bom": {
      "get": {
        "description": "Every line the job needs, with where each stands: ordered, received,\nreserved and still to order. Costs are null for a role that cannot see\nthem in the app.",
        "operationId": "materials.getBom",
        "parameters": [
          {
            "in": "path",
            "name": "job_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Job Id",
              "type": "string"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BomOut"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "No such job (ERR_NOT_FOUND).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Materials are switched off for this account (ERR_FEATURE_OFF).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "Get a job's bill of materials",
        "tags": [
          "Materials"
        ],
        "x-scopes": [
          "materials:read"
        ]
      }
    },
    "/v1/jobs/{job_id}/bom/lines": {
      "post": {
        "description": "Add a line to the job's bill of materials, optionally on a work order\nand one of its steps. Needs an office role or above.",
        "operationId": "materials.addBomLine",
        "parameters": [
          {
            "in": "path",
            "name": "job_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Job Id",
              "type": "string"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BomLineCreateIn"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BomLineOut"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "The job, material, stock item or work order is not in this account (ERR_NOT_FOUND).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Materials are switched off for this account (ERR_FEATURE_OFF).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "Add a bill of materials line",
        "tags": [
          "Materials"
        ],
        "x-scopes": [
          "materials:write"
        ]
      }
    },
    "/v1/jobs/{job_id}/bom/lines/{line_id}": {
      "delete": {
        "description": "Remove a line nothing has happened to yet. A line already on a\npurchase order, received, reserved or used is refused with\nERR_DELETE_BLOCKED; take it apart in the app. Needs an office role or\nabove.",
        "operationId": "materials.deleteBomLine",
        "parameters": [
          {
            "in": "path",
            "name": "job_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Job Id",
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "line_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Line Id",
              "type": "string"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BomLineDeletedOut"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "No such line on that job (ERR_NOT_FOUND).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "The line is on a purchase order, received, reserved or used (ERR_DELETE_BLOCKED), or materials are off (ERR_FEATURE_OFF).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "Remove a bill of materials line",
        "tags": [
          "Materials"
        ],
        "x-scopes": [
          "materials:write"
        ]
      },
      "patch": {
        "description": "Change a line. Only the fields you send change. Needs an office role\nor above.",
        "operationId": "materials.updateBomLine",
        "parameters": [
          {
            "in": "path",
            "name": "job_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Job Id",
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "line_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Line Id",
              "type": "string"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BomLineUpdateIn"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BomLineOut"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "No such line on that job (ERR_NOT_FOUND).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Materials are switched off for this account (ERR_FEATURE_OFF).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "Update a bill of materials line",
        "tags": [
          "Materials"
        ],
        "x-scopes": [
          "materials:write"
        ]
      }
    },
    "/v1/jobs/{job_id}/contacts": {
      "post": {
        "description": "Put a person on a job: somebody already in the account, or somebody new.\n\nTo attach an existing contact, send only `contact_id` (from\nGET /v1/contacts). Search before you create: one person should be one\ncontact, because incoming texts and calls are matched by phone number and\ntwo contacts sharing a number cannot be told apart.\n\nTo create a new contact on the job, send their details instead; at least\none of first_name, last_name, email or phone_number is needed.\n\nThe people already on the job stay on it. Attaching somebody who is\nalready there changes nothing and returns them. Returns the contact with\nthe jobs they are on. Needs an office role or above.",
        "operationId": "contacts.addToJob",
        "parameters": [
          {
            "in": "path",
            "name": "job_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Job Id",
              "type": "string"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/JobContactAddIn"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContactOut"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "No such job or contact in this account (ERR_NOT_FOUND).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "Add a contact to a job",
        "tags": [
          "Contacts"
        ],
        "x-scopes": [
          "contacts:write"
        ]
      }
    },
    "/v1/jobs/{job_id}/convert-to-project": {
      "post": {
        "description": "Win the opportunity: it becomes a job. Needs a manager role or above.",
        "operationId": "jobs.convert",
        "parameters": [
          {
            "in": "path",
            "name": "job_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Job Id",
              "type": "string"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobOut"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "No such job (ERR_NOT_FOUND).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "Convert an opportunity into a job",
        "tags": [
          "Jobs"
        ],
        "x-scopes": [
          "jobs:write"
        ]
      }
    },
    "/v1/jobs/{job_id}/emails": {
      "post": {
        "description": "Start an email conversation with contacts on a job.\n\nIt is sent from the connected mailbox of the user the credential acts as,\nand becomes a thread on the job's comms tab; replies thread back onto it.\nIf that user has not connected a mailbox the call is refused with\nERR_NO_MAILBOX: they connect one in the web app, signed in as\nthemselves, under Profile settings, Personal Inbox, Send email as me.\n\nEvery contact must be on the job and have an email address. Attach files\nalready on the job by id. A send that fails at the mailbox saves nothing.\nNeeds an office role or above.",
        "operationId": "comms.sendEmail",
        "parameters": [
          {
            "in": "path",
            "name": "job_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Job Id",
              "type": "string"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EmailIn"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmailSentOut"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "No such job, or a file is not on it (ERR_NOT_FOUND).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "The acting user has no connected mailbox (ERR_NO_MAILBOX).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "Email a job's contacts",
        "tags": [
          "Comms"
        ],
        "x-scopes": [
          "comms:send"
        ]
      }
    },
    "/v1/jobs/{job_id}/files": {
      "get": {
        "description": "The job's files newest first, as the job's Files tab lists them.\n\nNo download links here, to keep pages fast: get one from\n`GET /v1/files/{file_id}`. A user with a production role does not see\nfiles in folders hidden from production.",
        "operationId": "files.list",
        "parameters": [
          {
            "in": "path",
            "name": "job_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Job Id",
              "type": "string"
            }
          },
          {
            "description": "Only files in this folder.",
            "in": "query",
            "name": "folder_id",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "format": "uuid",
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only files in this folder.",
              "title": "Folder Id"
            }
          },
          {
            "description": "Only files changed at or after this time, oldest first.",
            "in": "query",
            "name": "updated_since",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "format": "date-time",
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only files changed at or after this time, oldest first.",
              "title": "Updated Since"
            }
          },
          {
            "description": "From the previous page's next_cursor.",
            "in": "query",
            "name": "cursor",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "From the previous page's next_cursor.",
              "title": "Cursor"
            }
          },
          {
            "description": "Page size, 1 to 200. Default 50.",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "maximum": 200,
                  "minimum": 1,
                  "type": "integer"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Page size, 1 to 200. Default 50.",
              "title": "Limit"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FilePage"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "No such job in this account (ERR_NOT_FOUND).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "List a job's files",
        "tags": [
          "Files"
        ],
        "x-scopes": [
          "files:read"
        ]
      }
    },
    "/v1/jobs/{job_id}/files/upload-url": {
      "post": {
        "description": "Get a signed URL to upload one file to a job. Step 1 of 3.\n\n1. Call this with the file's name, type and size.\n2. `PUT` the raw bytes to `upload_url` with exactly the\n   `required_headers`, before `expires_at` (about 30 minutes).\n3. Call `POST /v1/files/complete` with the `upload_token`.\n\nFiles can be up to 100 MB. The type is checked against the file types the\napp accepts, by extension. The file goes in `folder_id`, or the job's\nfirst folder when you do not name one. Needs an office role or above.",
        "operationId": "files.uploadUrl",
        "parameters": [
          {
            "in": "path",
            "name": "job_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Job Id",
              "type": "string"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UploadUrlIn"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UploadUrlOut"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "No such job in this account (ERR_NOT_FOUND).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "The job has no folder to put the file in (ERR_CONFLICT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "Start an upload",
        "tags": [
          "Files"
        ],
        "x-scopes": [
          "files:write"
        ]
      }
    },
    "/v1/jobs/{job_id}/move-to-lost": {
      "post": {
        "description": "Mark it lost, with an optional reason. Needs a manager role or above.",
        "operationId": "jobs.lose",
        "parameters": [
          {
            "in": "path",
            "name": "job_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Job Id",
              "type": "string"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/JobLostIn"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobOut"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "No such job (ERR_NOT_FOUND).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "Mark a lead or opportunity lost",
        "tags": [
          "Jobs"
        ],
        "x-scopes": [
          "jobs:write"
        ]
      }
    },
    "/v1/jobs/{job_id}/notes": {
      "get": {
        "description": "A job's notes, newest first. Page with `cursor`.\n\nIncludes the notes the product writes itself (`is_system`), such as the\nmessage a web form lead arrived with.",
        "operationId": "notes.list",
        "parameters": [
          {
            "in": "path",
            "name": "job_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Job Id",
              "type": "string"
            }
          },
          {
            "description": "From the previous page's next_cursor.",
            "in": "query",
            "name": "cursor",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "From the previous page's next_cursor.",
              "title": "Cursor"
            }
          },
          {
            "description": "Page size, 1 to 200. Default 50.",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "maximum": 200,
                  "minimum": 1,
                  "type": "integer"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Page size, 1 to 200. Default 50.",
              "title": "Limit"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NotePage"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "No such job in this account (ERR_NOT_FOUND).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "List a job's notes",
        "tags": [
          "Notes"
        ],
        "x-scopes": [
          "notes:read"
        ]
      },
      "post": {
        "description": "Post a note on a job, written by the user the credential acts as.\n\nIt appears at once on the job's page for everybody with it open, and the\npeople who follow the job's messages are notified, the same as a note\ntyped in the app.\n\nTo mention somebody, write `@[user_id:Name]` with an id from\nGET /v1/meta/users; they get a mention notification. `@[members:members]`\nmentions everyone on the job and `@[everyone:everyone]` the whole account,\nso use those sparingly.\n\nNotes cannot be edited or deleted through the API. Needs an office role\nor above.",
        "operationId": "notes.create",
        "parameters": [
          {
            "in": "path",
            "name": "job_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Job Id",
              "type": "string"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/NoteCreateIn"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NoteOut"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "No such job in this account (ERR_NOT_FOUND).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "Add a note to a job",
        "tags": [
          "Notes"
        ],
        "x-scopes": [
          "notes:write"
        ]
      }
    },
    "/v1/jobs/{job_id}/status": {
      "post": {
        "description": "Move a job to a main status or a phase. The same rules as the app apply:\na job with estimates cannot go back to Lead, and closing needs its\ninvoices settled.",
        "operationId": "jobs.setStatus",
        "parameters": [
          {
            "in": "path",
            "name": "job_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Job Id",
              "type": "string"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/JobStatusIn"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobOut"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "No such job (ERR_NOT_FOUND).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "Move a job to a status",
        "tags": [
          "Jobs"
        ],
        "x-scopes": [
          "jobs:write"
        ]
      }
    },
    "/v1/jobs/{job_id}/tasks": {
      "get": {
        "description": "A job's tasks, newest first, or, with `updated_since`, every task on\nthe job changed since then, oldest first. Page with `cursor`.",
        "operationId": "tasks.list",
        "parameters": [
          {
            "in": "path",
            "name": "job_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Job Id",
              "type": "string"
            }
          },
          {
            "description": "true for done tasks only, false for open ones only.",
            "in": "query",
            "name": "completed",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "boolean"
                },
                {
                  "type": "null"
                }
              ],
              "description": "true for done tasks only, false for open ones only.",
              "title": "Completed"
            }
          },
          {
            "description": "Only tasks changed at or after this time, oldest first. How to keep another system in step.",
            "in": "query",
            "name": "updated_since",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "format": "date-time",
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only tasks changed at or after this time, oldest first. How to keep another system in step.",
              "title": "Updated Since"
            }
          },
          {
            "description": "From the previous page's next_cursor.",
            "in": "query",
            "name": "cursor",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "From the previous page's next_cursor.",
              "title": "Cursor"
            }
          },
          {
            "description": "Page size, 1 to 200. Default 50.",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "maximum": 200,
                  "minimum": 1,
                  "type": "integer"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Page size, 1 to 200. Default 50.",
              "title": "Limit"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TaskPage"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "No such job in this account (ERR_NOT_FOUND).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "List a job's tasks",
        "tags": [
          "Tasks"
        ],
        "x-scopes": [
          "tasks:read"
        ]
      },
      "post": {
        "description": "Create a task on a job and assign it.\n\nA task always has at least one person on it: send their user ids (from\nGET /v1/meta/users) in `assignee_user_ids`. A task with nobody assigned is\nrefused rather than quietly given to the credential's own user. The\npeople assigned are notified, as they are for a task made in the app.\n\nNew tasks start at the account's Incomplete status unless you send\n`status_id`. Needs an office role or above.",
        "operationId": "tasks.create",
        "parameters": [
          {
            "in": "path",
            "name": "job_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Job Id",
              "type": "string"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TaskCreateIn"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TaskOut"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "No such job in this account (ERR_NOT_FOUND).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "Add a task to a job",
        "tags": [
          "Tasks"
        ],
        "x-scopes": [
          "tasks:write"
        ]
      }
    },
    "/v1/jobs/{job_id}/threads": {
      "get": {
        "description": "The job's conversations with customers, newest first: subject,\ncategory, when the last message came and how many there are.",
        "operationId": "comms.listThreads",
        "parameters": [
          {
            "in": "path",
            "name": "job_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Job Id",
              "type": "string"
            }
          },
          {
            "description": "Include archived threads.",
            "in": "query",
            "name": "include_archived",
            "required": false,
            "schema": {
              "default": false,
              "description": "Include archived threads.",
              "title": "Include Archived",
              "type": "boolean"
            }
          },
          {
            "description": "From the previous page's next_cursor.",
            "in": "query",
            "name": "cursor",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "From the previous page's next_cursor.",
              "title": "Cursor"
            }
          },
          {
            "description": "Page size, 1 to 200. Default 50.",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "maximum": 200,
                  "minimum": 1,
                  "type": "integer"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Page size, 1 to 200. Default 50.",
              "title": "Limit"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ThreadPage"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "No such job in this account (ERR_NOT_FOUND).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "List a job's threads",
        "tags": [
          "Comms"
        ],
        "x-scopes": [
          "notes:read"
        ]
      }
    },
    "/v1/leads/create": {
      "post": {
        "description": "Put a new lead into the account's pipeline.\n\nThe lead appears immediately on the account's pipeline board and everyone in\nthe office is notified, so treat a 201 as \"a person will see this\".\n\n**Send an `Idempotency-Key` header.** Any string you generate per submission\n- a UUID, your own form-submission id. If the same key arrives twice we\nreturn the first result instead of creating a second lead, which is what\nstops a network timeout or an automatic retry from putting the same customer\nin the pipeline twice. This route accepts a call without one, for the forms\nthat were built before it was required; every other write requires it.\n\n**Only `job_name` is required.** Send whatever the enquiry captured; a lead\nwith a name and a phone number is more useful than no lead at all.\n\n**Check `warnings` in the response.** A 201 with warnings means the lead was\ncreated but part of your payload could not be applied - usually a field key\nthat no longer exists because somebody changed the form. It is the only\nsignal you will get that your integration has drifted, so log it.",
        "operationId": "leads.create",
        "parameters": [
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LeadCreate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "examples": {
                  "created": {
                    "summary": "Created",
                    "value": {
                      "contact_id": "b2d4e6f8-1a3c-5e7b-9d0f-2a4c6e8b0d1f",
                      "created_at": "2026-09-10T14:22:05.412000+00:00",
                      "duplicate": false,
                      "id": "3f9a1c77-5e3b-4a02-9d8e-2c7b6a1f0e4d",
                      "job_name": "Whitfield kitchen remodel",
                      "reference": "J1042",
                      "stage": "lead",
                      "status": "Lead",
                      "warnings": []
                    }
                  },
                  "created_with_warnings": {
                    "summary": "Created, with part of the payload dropped",
                    "value": {
                      "contact_id": "b2d4e6f8-1a3c-5e7b-9d0f-2a4c6e8b0d1f",
                      "created_at": "2026-09-10T14:22:05.412000+00:00",
                      "duplicate": false,
                      "id": "3f9a1c77-5e3b-4a02-9d8e-2c7b6a1f0e4d",
                      "job_name": "Whitfield kitchen remodel",
                      "reference": "J1042",
                      "stage": "lead",
                      "status": "Lead",
                      "warnings": [
                        "Form field 'budget_range' is not a field on this form; it was not saved."
                      ]
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/LeadCreated"
                }
              }
            },
            "description": "The lead was created.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "An earlier request with the same Idempotency-Key did not finish (ERR_IDEMPOTENCY_IN_PROGRESS).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "Create a lead",
        "tags": [
          "Leads"
        ],
        "x-scopes": [
          "leads:write"
        ]
      }
    },
    "/v1/materials": {
      "get": {
        "description": "The shop's materials A to Z, each with the stock items it is bought\nas. Page with `cursor`.",
        "operationId": "materials.list",
        "parameters": [
          {
            "description": "Only this material type, from GET /v1/meta/material-types.",
            "in": "query",
            "name": "type_id",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "format": "uuid",
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only this material type, from GET /v1/meta/material-types.",
              "title": "Type Id"
            }
          },
          {
            "description": "Words of the name, or a part number typed whole.",
            "in": "query",
            "name": "q",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "maxLength": 200,
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Words of the name, or a part number typed whole.",
              "title": "Q"
            }
          },
          {
            "description": "Also return materials the shop no longer uses.",
            "in": "query",
            "name": "include_inactive",
            "required": false,
            "schema": {
              "default": false,
              "description": "Also return materials the shop no longer uses.",
              "title": "Include Inactive",
              "type": "boolean"
            }
          },
          {
            "description": "From the previous page's next_cursor.",
            "in": "query",
            "name": "cursor",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "From the previous page's next_cursor.",
              "title": "Cursor"
            }
          },
          {
            "description": "Page size, 1 to 200. Default 50.",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "maximum": 200,
                  "minimum": 1,
                  "type": "integer"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Page size, 1 to 200. Default 50.",
              "title": "Limit"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MaterialPage"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Materials are switched off for this account (ERR_FEATURE_OFF).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "List materials",
        "tags": [
          "Materials"
        ],
        "x-scopes": [
          "materials:read"
        ]
      }
    },
    "/v1/materials/{material_id}": {
      "get": {
        "description": "One material with its stock items.",
        "operationId": "materials.get",
        "parameters": [
          {
            "in": "path",
            "name": "material_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Material Id",
              "type": "string"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MaterialOut"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "No such material (ERR_NOT_FOUND).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Materials are switched off for this account (ERR_FEATURE_OFF).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "Get a material",
        "tags": [
          "Materials"
        ],
        "x-scopes": [
          "materials:read"
        ]
      }
    },
    "/v1/meta/custom-fields": {
      "get": {
        "description": "The custom fields this account has set up on jobs. Same as\n`GET /v1/custom-fields`, under the lookups everything else lives in.",
        "operationId": "meta.customFieldsV2",
        "parameters": [
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/CustomFieldOut"
                  },
                  "title": "Response Meta.Customfieldsv2",
                  "type": "array"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "List the account's job fields",
        "tags": [
          "Meta"
        ],
        "x-scopes": [
          "meta:read"
        ]
      }
    },
    "/v1/meta/departments": {
      "get": {
        "description": "The account's departments, for assigning tasks and events.",
        "operationId": "meta.departments",
        "parameters": [
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/DepartmentOut"
                  },
                  "title": "Response Meta.Departments",
                  "type": "array"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "List departments",
        "tags": [
          "Meta"
        ],
        "x-scopes": [
          "meta:read"
        ]
      }
    },
    "/v1/meta/estimate-statuses": {
      "get": {
        "description": "The statuses an estimate can be in. `locks_editing` marks the ones in\nwhich the document can no longer be changed (sent, signed).",
        "operationId": "meta.estimateStatuses",
        "parameters": [
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/SimpleStatusOut"
                  },
                  "title": "Response Meta.Estimatestatuses",
                  "type": "array"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "List estimate statuses",
        "tags": [
          "Meta"
        ],
        "x-scopes": [
          "meta:read"
        ]
      }
    },
    "/v1/meta/invoice-statuses": {
      "get": {
        "description": "The statuses an invoice can be in.",
        "operationId": "meta.invoiceStatuses",
        "parameters": [
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/SimpleStatusOut"
                  },
                  "title": "Response Meta.Invoicestatuses",
                  "type": "array"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "List invoice statuses",
        "tags": [
          "Meta"
        ],
        "x-scopes": [
          "meta:read"
        ]
      }
    },
    "/v1/meta/job-forms": {
      "get": {
        "description": "The job form templates this account uses. Same as `GET /v1/job-forms`.",
        "operationId": "meta.jobFormsV2",
        "parameters": [
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/FormSchemaOut"
                  },
                  "title": "Response Meta.Jobformsv2",
                  "type": "array"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "List the account's job forms",
        "tags": [
          "Meta"
        ],
        "x-scopes": [
          "meta:read"
        ]
      }
    },
    "/v1/meta/job-statuses": {
      "get": {
        "description": "The account's pipeline: main statuses in order, and the phases under them.\n\nPass an `id` from here as `status_id` to `POST /v1/jobs/{id}/status`.\nAccounts rename and add statuses, so look ids up when your integration\nstarts rather than hard-coding them.",
        "operationId": "meta.jobStatuses",
        "parameters": [
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/JobStatusOut"
                  },
                  "title": "Response Meta.Jobstatuses",
                  "type": "array"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "List job statuses",
        "tags": [
          "Meta"
        ],
        "x-scopes": [
          "meta:read"
        ]
      }
    },
    "/v1/meta/material-types": {
      "get": {
        "description": "The kinds of material the account stocks.",
        "operationId": "meta.materialTypes",
        "parameters": [
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/MaterialTypeOut"
                  },
                  "title": "Response Meta.Materialtypes",
                  "type": "array"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "List material types",
        "tags": [
          "Meta"
        ],
        "x-scopes": [
          "meta:read"
        ]
      }
    },
    "/v1/meta/product-categories": {
      "get": {
        "description": "The product catalog's categories.",
        "operationId": "meta.productCategories",
        "parameters": [
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/ProductCategoryOut"
                  },
                  "title": "Response Meta.Productcategories",
                  "type": "array"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "List product categories",
        "tags": [
          "Meta"
        ],
        "x-scopes": [
          "meta:read"
        ]
      }
    },
    "/v1/meta/task-statuses": {
      "get": {
        "description": "The statuses a task can be in. `is_complete` marks the done ones.",
        "operationId": "meta.taskStatuses",
        "parameters": [
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/SimpleStatusOut"
                  },
                  "title": "Response Meta.Taskstatuses",
                  "type": "array"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "List task statuses",
        "tags": [
          "Meta"
        ],
        "x-scopes": [
          "meta:read"
        ]
      }
    },
    "/v1/meta/units": {
      "get": {
        "description": "Units used on products and line items.",
        "operationId": "meta.units",
        "parameters": [
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/app__api__v1__meta__schema__UnitOut"
                  },
                  "title": "Response Meta.Units",
                  "type": "array"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "List units of measure",
        "tags": [
          "Meta"
        ],
        "x-scopes": [
          "meta:read"
        ]
      }
    },
    "/v1/meta/users": {
      "get": {
        "description": "Active members with their role, for assigning tasks, events and project\nmanagers. Email addresses are not included.",
        "operationId": "meta.users",
        "parameters": [
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/UserOut"
                  },
                  "title": "Response Meta.Users",
                  "type": "array"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "List the account's users",
        "tags": [
          "Meta"
        ],
        "x-scopes": [
          "meta:read"
        ]
      }
    },
    "/v1/meta/work-order-types": {
      "get": {
        "description": "Each kind of work order the account uses, with the statuses it moves\nthrough in order.",
        "operationId": "meta.workOrderTypes",
        "parameters": [
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/WorkOrderTypeOut"
                  },
                  "title": "Response Meta.Workordertypes",
                  "type": "array"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "List work order types and their statuses",
        "tags": [
          "Meta"
        ],
        "x-scopes": [
          "meta:read"
        ]
      }
    },
    "/v1/payments": {
      "get": {
        "description": "Payments newest first, or, with `updated_since`, everything changed\nsince then, oldest first. Read-only: payments are taken and recorded in\nthe app. Needs `invoices:read` and an office role or above.",
        "operationId": "payments.list",
        "parameters": [
          {
            "description": "Only this job's payments.",
            "in": "query",
            "name": "job_id",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "format": "uuid",
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only this job's payments.",
              "title": "Job Id"
            }
          },
          {
            "description": "Only payments recorded against or applied to this invoice.",
            "in": "query",
            "name": "invoice_id",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "format": "uuid",
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only payments recorded against or applied to this invoice.",
              "title": "Invoice Id"
            }
          },
          {
            "description": "Only payments changed at or after this time, oldest first.",
            "in": "query",
            "name": "updated_since",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "format": "date-time",
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only payments changed at or after this time, oldest first.",
              "title": "Updated Since"
            }
          },
          {
            "description": "From the previous page's next_cursor.",
            "in": "query",
            "name": "cursor",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "From the previous page's next_cursor.",
              "title": "Cursor"
            }
          },
          {
            "description": "Page size, 1 to 200. Default 50.",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "maximum": 200,
                  "minimum": 1,
                  "type": "integer"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Page size, 1 to 200. Default 50.",
              "title": "Limit"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentPage"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "List payments",
        "tags": [
          "Invoices"
        ],
        "x-scopes": [
          "invoices:read"
        ]
      }
    },
    "/v1/products": {
      "get": {
        "description": "Products newest first, or with `updated_since` the ones changed since\nthen, oldest first. Prices and costs are null for a role that cannot\nsee them in the app.",
        "operationId": "products.list",
        "parameters": [
          {
            "description": "Search the name, display name and SKU.",
            "in": "query",
            "name": "q",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "maxLength": 200,
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Search the name, display name and SKU.",
              "title": "Q"
            }
          },
          {
            "description": "A category and the ones directly under it.",
            "in": "query",
            "name": "category_id",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "format": "uuid",
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A category and the ones directly under it.",
              "title": "Category Id"
            }
          },
          {
            "description": "Also return archived products.",
            "in": "query",
            "name": "include_archived",
            "required": false,
            "schema": {
              "default": false,
              "description": "Also return archived products.",
              "title": "Include Archived",
              "type": "boolean"
            }
          },
          {
            "description": "Only products changed at or after this time, oldest first. How to keep another system in step.",
            "in": "query",
            "name": "updated_since",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "format": "date-time",
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only products changed at or after this time, oldest first. How to keep another system in step.",
              "title": "Updated Since"
            }
          },
          {
            "description": "From the previous page's next_cursor.",
            "in": "query",
            "name": "cursor",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "From the previous page's next_cursor.",
              "title": "Cursor"
            }
          },
          {
            "description": "Page size, 1 to 200. Default 50.",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "maximum": 200,
                  "minimum": 1,
                  "type": "integer"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Page size, 1 to 200. Default 50.",
              "title": "Limit"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProductPage"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "List products",
        "tags": [
          "Products"
        ],
        "x-scopes": [
          "products:read"
        ]
      },
      "post": {
        "description": "Add a product to the price book. Needs a manager role or above.",
        "operationId": "products.create",
        "parameters": [
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ProductCreateIn"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProductOut"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "The unit, category, stock item or supplier is not in this account (ERR_NOT_FOUND).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "The SKU is already in use (ERR_CONFLICT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "Create a product",
        "tags": [
          "Products"
        ],
        "x-scopes": [
          "products:write"
        ]
      }
    },
    "/v1/products/{product_id}": {
      "get": {
        "description": "One product.",
        "operationId": "products.get",
        "parameters": [
          {
            "in": "path",
            "name": "product_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Product Id",
              "type": "string"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProductOut"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "No such product in this account (ERR_NOT_FOUND).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "Get a product",
        "tags": [
          "Products"
        ],
        "x-scopes": [
          "products:read"
        ]
      },
      "patch": {
        "description": "Change a product. Only the fields you send change. Needs a manager\nrole or above.",
        "operationId": "products.update",
        "parameters": [
          {
            "in": "path",
            "name": "product_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Product Id",
              "type": "string"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ProductUpdateIn"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProductOut"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "No such product in this account (ERR_NOT_FOUND).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "The SKU is already in use (ERR_CONFLICT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "Update a product",
        "tags": [
          "Products"
        ],
        "x-scopes": [
          "products:write"
        ]
      }
    },
    "/v1/purchase-orders": {
      "get": {
        "description": "Purchase orders newest first, or with `updated_since` the ones changed\nsince then, oldest first. Lines are on the single order.",
        "operationId": "purchaseOrders.list",
        "parameters": [
          {
            "description": "Only this supplier's orders.",
            "in": "query",
            "name": "vendor_id",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "format": "uuid",
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only this supplier's orders.",
              "title": "Vendor Id"
            }
          },
          {
            "description": "Only this job's orders.",
            "in": "query",
            "name": "job_id",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "format": "uuid",
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only this job's orders.",
              "title": "Job Id"
            }
          },
          {
            "description": "draft, submitted, partial, received or cancelled; several separated by commas.",
            "in": "query",
            "name": "status",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "draft, submitted, partial, received or cancelled; several separated by commas.",
              "title": "Status"
            }
          },
          {
            "description": "Only orders changed at or after this time, oldest first. How to keep another system in step.",
            "in": "query",
            "name": "updated_since",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "format": "date-time",
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only orders changed at or after this time, oldest first. How to keep another system in step.",
              "title": "Updated Since"
            }
          },
          {
            "description": "From the previous page's next_cursor.",
            "in": "query",
            "name": "cursor",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "From the previous page's next_cursor.",
              "title": "Cursor"
            }
          },
          {
            "description": "Page size, 1 to 200. Default 50.",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "maximum": 200,
                  "minimum": 1,
                  "type": "integer"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Page size, 1 to 200. Default 50.",
              "title": "Limit"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PurchaseOrderPage"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Purchasing is switched off for this account (ERR_FEATURE_OFF).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "List purchase orders",
        "tags": [
          "Purchase orders"
        ],
        "x-scopes": [
          "purchasing:read"
        ]
      },
      "post": {
        "description": "Create a purchase order for a job (`kind: job`) or for the shelf\n(`kind: stock`), with its lines. Every line is checked before the order\nis made, so a bad line refuses the whole call. Needs a manager role or\nabove.",
        "operationId": "purchaseOrders.create",
        "parameters": [
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PurchaseOrderCreateIn"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PurchaseOrderOut"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "The supplier, job or a stock item is not in this account (ERR_NOT_FOUND).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Purchasing is switched off for this account (ERR_FEATURE_OFF).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "Create a purchase order",
        "tags": [
          "Purchase orders"
        ],
        "x-scopes": [
          "purchasing:write"
        ]
      }
    },
    "/v1/purchase-orders/{po_id}": {
      "get": {
        "description": "One purchase order with its lines and how much of each has arrived.",
        "operationId": "purchaseOrders.get",
        "parameters": [
          {
            "in": "path",
            "name": "po_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Po Id",
              "type": "string"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PurchaseOrderOut"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "No such purchase order in this account (ERR_NOT_FOUND).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Purchasing is switched off for this account (ERR_FEATURE_OFF).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "Get a purchase order",
        "tags": [
          "Purchase orders"
        ],
        "x-scopes": [
          "purchasing:read"
        ]
      },
      "patch": {
        "description": "Change an order's details, or move it between draft, submitted and\ncancelled. Only the fields you send change. Needs a manager role or\nabove.",
        "operationId": "purchaseOrders.update",
        "parameters": [
          {
            "in": "path",
            "name": "po_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Po Id",
              "type": "string"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PurchaseOrderUpdateIn"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PurchaseOrderOut"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "No such purchase order in this account (ERR_NOT_FOUND).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Purchasing is switched off for this account (ERR_FEATURE_OFF).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "Update a purchase order",
        "tags": [
          "Purchase orders"
        ],
        "x-scopes": [
          "purchasing:write"
        ]
      }
    },
    "/v1/purchase-orders/{po_id}/lines": {
      "post": {
        "description": "Add a line; the order's totals follow. Returns the whole order.\nNeeds a manager role or above.",
        "operationId": "purchaseOrders.addLine",
        "parameters": [
          {
            "in": "path",
            "name": "po_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Po Id",
              "type": "string"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/POLineIn"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PurchaseOrderOut"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "No such purchase order in this account (ERR_NOT_FOUND).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Purchasing is switched off for this account (ERR_FEATURE_OFF).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "Add a purchase order line",
        "tags": [
          "Purchase orders"
        ],
        "x-scopes": [
          "purchasing:write"
        ]
      }
    },
    "/v1/purchase-orders/{po_id}/lines/{line_id}": {
      "patch": {
        "description": "Change a line; the order's totals follow. Only the fields you send\nchange. Returns the whole order. Needs a manager role or above.",
        "operationId": "purchaseOrders.updateLine",
        "parameters": [
          {
            "in": "path",
            "name": "po_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Po Id",
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "line_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Line Id",
              "type": "string"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/POLineUpdateIn"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PurchaseOrderOut"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "No such order, or no such line on it (ERR_NOT_FOUND).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Purchasing is switched off for this account (ERR_FEATURE_OFF).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "Update a purchase order line",
        "tags": [
          "Purchase orders"
        ],
        "x-scopes": [
          "purchasing:write"
        ]
      }
    },
    "/v1/purchase-orders/{po_id}/receive": {
      "post": {
        "description": "Record what arrived against the order, line by line.\n\nThe order moves to partial or received from the quantities, and the\nbill of materials lines it was bought for follow, the same as \"Mark\ndelivered\" in the app. When the account tracks inventory each line also\nbecomes stock at `to_location_id`. Receiving more than a line still owes\nis refused; accept an over-delivery in the app. Needs a manager role or\nabove.",
        "operationId": "purchaseOrders.receive",
        "parameters": [
          {
            "in": "path",
            "name": "po_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Po Id",
              "type": "string"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReceiveIn"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReceiveResultOut"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "No such purchase order in this account (ERR_NOT_FOUND).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "More than a line still owes (ERR_CONFLICT; the sentence says how much is outstanding), the order was cancelled, or purchasing is off (ERR_FEATURE_OFF).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "Record a delivery",
        "tags": [
          "Purchase orders"
        ],
        "x-scopes": [
          "purchasing:write"
        ]
      }
    },
    "/v1/stock-items/{item_id}": {
      "get": {
        "description": "One stock item: a way a material is bought, with its part numbers,\nstandard cost and, when the account tracks inventory, what is on hand.",
        "operationId": "materials.getStockItem",
        "parameters": [
          {
            "in": "path",
            "name": "item_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Item Id",
              "type": "string"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StockItemOut"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "No such stock item (ERR_NOT_FOUND).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Materials are switched off for this account (ERR_FEATURE_OFF).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "Get a stock item",
        "tags": [
          "Materials"
        ],
        "x-scopes": [
          "materials:read"
        ]
      }
    },
    "/v1/tasks/{task_id}": {
      "get": {
        "description": "One task, with who it is assigned to and where it stands.",
        "operationId": "tasks.get",
        "parameters": [
          {
            "in": "path",
            "name": "task_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Task Id",
              "type": "string"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TaskOut"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "No such task in this account (ERR_NOT_FOUND).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "Get a task",
        "tags": [
          "Tasks"
        ],
        "x-scopes": [
          "tasks:read"
        ]
      },
      "patch": {
        "description": "Change a task's title, description, due date, people or status. Only\nthe fields you send change, and a list you send replaces the one there.\n\nTo mark a task done or open again, the complete and reopen actions are\nsimpler than choosing a status. Needs an office role or above.",
        "operationId": "tasks.update",
        "parameters": [
          {
            "in": "path",
            "name": "task_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Task Id",
              "type": "string"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TaskUpdateIn"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TaskOut"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "No such task in this account (ERR_NOT_FOUND).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "Update a task",
        "tags": [
          "Tasks"
        ],
        "x-scopes": [
          "tasks:write"
        ]
      }
    },
    "/v1/tasks/{task_id}/complete": {
      "post": {
        "description": "Mark a task done: it moves to the account's Complete status and\n`completed_at` is set to now. Needs an office role or above.",
        "operationId": "tasks.complete",
        "parameters": [
          {
            "in": "path",
            "name": "task_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Task Id",
              "type": "string"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TaskOut"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "No such task in this account (ERR_NOT_FOUND).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "Complete a task",
        "tags": [
          "Tasks"
        ],
        "x-scopes": [
          "tasks:write"
        ]
      }
    },
    "/v1/tasks/{task_id}/reopen": {
      "post": {
        "description": "Open a completed task again: it moves back to the account's Incomplete\nstatus and `completed_at` is cleared. Tasks are never deleted through the\nAPI; reopen or complete them instead. Needs an office role or above.",
        "operationId": "tasks.reopen",
        "parameters": [
          {
            "in": "path",
            "name": "task_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Task Id",
              "type": "string"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TaskOut"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "No such task in this account (ERR_NOT_FOUND).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "Reopen a task",
        "tags": [
          "Tasks"
        ],
        "x-scopes": [
          "tasks:write"
        ]
      }
    },
    "/v1/time-entries": {
      "get": {
        "description": "Time entries that started between `start` and `end`, oldest first.\n\nThe days are the account's own: an entry clocked in at 23:30 local time\nbelongs to that day, whatever the UTC date. The range is required and\nat most 31 days; read a longer period a month at a time. A production\nrole reads only their own entries; asking for somebody else's is\nrefused with ERR_ROLE_REQUIRED.",
        "operationId": "time.list",
        "parameters": [
          {
            "description": "First day, YYYY-MM-DD, on the account's own calendar.",
            "in": "query",
            "name": "start",
            "required": true,
            "schema": {
              "description": "First day, YYYY-MM-DD, on the account's own calendar.",
              "format": "date",
              "title": "Start",
              "type": "string"
            }
          },
          {
            "description": "Last day, inclusive. At most 31 days after start.",
            "in": "query",
            "name": "end",
            "required": true,
            "schema": {
              "description": "Last day, inclusive. At most 31 days after start.",
              "format": "date",
              "title": "End",
              "type": "string"
            }
          },
          {
            "description": "Only this person's time, from GET /v1/meta/users.",
            "in": "query",
            "name": "user_id",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "format": "uuid",
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only this person's time, from GET /v1/meta/users.",
              "title": "User Id"
            }
          },
          {
            "description": "Only time on this job.",
            "in": "query",
            "name": "job_id",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "format": "uuid",
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only time on this job.",
              "title": "Job Id"
            }
          },
          {
            "description": "From the previous page's next_cursor.",
            "in": "query",
            "name": "cursor",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "From the previous page's next_cursor.",
              "title": "Cursor"
            }
          },
          {
            "description": "Page size, 1 to 200. Default 50.",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "maximum": 200,
                  "minimum": 1,
                  "type": "integer"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Page size, 1 to 200. Default 50.",
              "title": "Limit"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TimeEntryPage"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "List time entries",
        "tags": [
          "Time"
        ],
        "x-scopes": [
          "time:read"
        ]
      }
    },
    "/v1/vendors": {
      "get": {
        "description": "The account's suppliers, newest first, or with `updated_since` the\nones changed since then, oldest first.",
        "operationId": "vendors.list",
        "parameters": [
          {
            "description": "Search the name, supplier number and city.",
            "in": "query",
            "name": "q",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "maxLength": 200,
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Search the name, supplier number and city.",
              "title": "Q"
            }
          },
          {
            "description": "Also return archived suppliers.",
            "in": "query",
            "name": "include_archived",
            "required": false,
            "schema": {
              "default": false,
              "description": "Also return archived suppliers.",
              "title": "Include Archived",
              "type": "boolean"
            }
          },
          {
            "description": "Only suppliers changed at or after this time, oldest first.",
            "in": "query",
            "name": "updated_since",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "format": "date-time",
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only suppliers changed at or after this time, oldest first.",
              "title": "Updated Since"
            }
          },
          {
            "description": "From the previous page's next_cursor.",
            "in": "query",
            "name": "cursor",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "From the previous page's next_cursor.",
              "title": "Cursor"
            }
          },
          {
            "description": "Page size, 1 to 200. Default 50.",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "maximum": 200,
                  "minimum": 1,
                  "type": "integer"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Page size, 1 to 200. Default 50.",
              "title": "Limit"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VendorPage"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Suppliers are switched off for this account (ERR_FEATURE_OFF).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "List suppliers",
        "tags": [
          "Vendors"
        ],
        "x-scopes": [
          "purchasing:read"
        ]
      },
      "post": {
        "description": "Add a supplier, with its contacts. Needs a manager role or above.",
        "operationId": "vendors.create",
        "parameters": [
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/VendorCreateIn"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VendorOut"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Suppliers are switched off for this account (ERR_FEATURE_OFF).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "Create a supplier",
        "tags": [
          "Vendors"
        ],
        "x-scopes": [
          "purchasing:write"
        ]
      }
    },
    "/v1/vendors/{vendor_id}": {
      "get": {
        "description": "One supplier with its contacts.",
        "operationId": "vendors.get",
        "parameters": [
          {
            "in": "path",
            "name": "vendor_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Vendor Id",
              "type": "string"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VendorOut"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "No such supplier in this account (ERR_NOT_FOUND).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Suppliers are switched off for this account (ERR_FEATURE_OFF).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "Get a supplier",
        "tags": [
          "Vendors"
        ],
        "x-scopes": [
          "purchasing:read"
        ]
      },
      "patch": {
        "description": "Change a supplier's details. Only the fields you send change. Needs a\nmanager role or above.",
        "operationId": "vendors.update",
        "parameters": [
          {
            "in": "path",
            "name": "vendor_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Vendor Id",
              "type": "string"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/VendorUpdateIn"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VendorOut"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "No such supplier in this account (ERR_NOT_FOUND).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Suppliers are switched off for this account (ERR_FEATURE_OFF).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "Update a supplier",
        "tags": [
          "Vendors"
        ],
        "x-scopes": [
          "purchasing:write"
        ]
      }
    },
    "/v1/webhook-deliveries/{delivery_id}": {
      "get": {
        "description": "One delivery: the exact body sent, and every attempt with what your\nreceiver answered.",
        "operationId": "webhooks.delivery",
        "parameters": [
          {
            "in": "path",
            "name": "delivery_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Delivery Id",
              "type": "string"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeliveryDetailOut"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "No such delivery (ERR_NOT_FOUND).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "Get a delivery",
        "tags": [
          "Webhooks"
        ],
        "x-admin": true,
        "x-scopes": [
          "webhooks:manage"
        ]
      }
    },
    "/v1/webhook-deliveries/{delivery_id}/retry": {
      "post": {
        "description": "Send a failed or dead delivery once more, now. Counts as one call.",
        "operationId": "webhooks.retry",
        "parameters": [
          {
            "in": "path",
            "name": "delivery_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Delivery Id",
              "type": "string"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeliveryDetailOut"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "No such delivery (ERR_NOT_FOUND).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not failed or dead, or the endpoint is off.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "Retry a failed delivery",
        "tags": [
          "Webhooks"
        ],
        "x-admin": true,
        "x-scopes": [
          "webhooks:manage"
        ]
      }
    },
    "/v1/webhook-event-types": {
      "get": {
        "description": "Every event an endpoint can subscribe to. The payload of each is in\nthe `webhooks` section of this document.",
        "operationId": "webhooks.eventTypes",
        "parameters": [
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/EventTypeOut"
                  },
                  "title": "Response Webhooks.Eventtypes",
                  "type": "array"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "List webhook event types",
        "tags": [
          "Webhooks"
        ],
        "x-scopes": [
          "meta:read"
        ]
      }
    },
    "/v1/webhooks": {
      "get": {
        "description": "The account's endpoints, at most 10. Secrets are never listed.",
        "operationId": "webhooks.list",
        "parameters": [
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/EndpointOut"
                  },
                  "title": "Response Webhooks.List",
                  "type": "array"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "List webhook endpoints",
        "tags": [
          "Webhooks"
        ],
        "x-admin": true,
        "x-scopes": [
          "webhooks:manage"
        ]
      },
      "post": {
        "description": "Start sending events to a URL. The response carries the signing\nsecret; store it to verify each delivery's `WoodSystems-Signature`.\n\nThe URL must be https and public: private, loopback, link-local and\nmetadata addresses are refused, and checked again at every send.",
        "operationId": "webhooks.create",
        "parameters": [
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EndpointIn"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EndpointWithSecretOut"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "Add a webhook endpoint",
        "tags": [
          "Webhooks"
        ],
        "x-admin": true,
        "x-scopes": [
          "webhooks:manage"
        ]
      }
    },
    "/v1/webhooks/{endpoint_id}": {
      "delete": {
        "description": "Stop sending to this URL for good. Its delivery log goes with it.",
        "operationId": "webhooks.delete",
        "parameters": [
          {
            "in": "path",
            "name": "endpoint_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Endpoint Id",
              "type": "string"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "No such endpoint (ERR_NOT_FOUND).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "Delete a webhook endpoint",
        "tags": [
          "Webhooks"
        ],
        "x-admin": true,
        "x-scopes": [
          "webhooks:manage"
        ]
      },
      "get": {
        "description": "One endpoint, with its recent failure count.",
        "operationId": "webhooks.get",
        "parameters": [
          {
            "in": "path",
            "name": "endpoint_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Endpoint Id",
              "type": "string"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EndpointOut"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "No such endpoint (ERR_NOT_FOUND).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "Get a webhook endpoint",
        "tags": [
          "Webhooks"
        ],
        "x-admin": true,
        "x-scopes": [
          "webhooks:manage"
        ]
      },
      "patch": {
        "description": "Change the URL, description or events, or switch it off and on.\nSwitching it back on clears the failure record.",
        "operationId": "webhooks.update",
        "parameters": [
          {
            "in": "path",
            "name": "endpoint_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Endpoint Id",
              "type": "string"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EndpointUpdateIn"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EndpointOut"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "No such endpoint (ERR_NOT_FOUND).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "Change a webhook endpoint",
        "tags": [
          "Webhooks"
        ],
        "x-admin": true,
        "x-scopes": [
          "webhooks:manage"
        ]
      }
    },
    "/v1/webhooks/{endpoint_id}/deliveries": {
      "get": {
        "description": "Newest first. Deliveries are kept for 30 days.",
        "operationId": "webhooks.deliveries",
        "parameters": [
          {
            "in": "path",
            "name": "endpoint_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Endpoint Id",
              "type": "string"
            }
          },
          {
            "description": "pending, sending, delivered, failed or dead.",
            "in": "query",
            "name": "status",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "pending, sending, delivered, failed or dead.",
              "title": "Status"
            }
          },
          {
            "in": "query",
            "name": "cursor",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Cursor"
            }
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "maximum": 100,
                  "minimum": 1,
                  "type": "integer"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Limit"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeliveryPage"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "No such endpoint (ERR_NOT_FOUND).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "List an endpoint's deliveries",
        "tags": [
          "Webhooks"
        ],
        "x-admin": true,
        "x-scopes": [
          "webhooks:manage"
        ]
      }
    },
    "/v1/webhooks/{endpoint_id}/rotate-secret": {
      "post": {
        "description": "A new secret. For 24 hours every delivery is signed with both the new\nand the old one, so your receiver can be updated without missing events.",
        "operationId": "webhooks.rotateSecret",
        "parameters": [
          {
            "in": "path",
            "name": "endpoint_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Endpoint Id",
              "type": "string"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EndpointWithSecretOut"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "No such endpoint (ERR_NOT_FOUND).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "Rotate a webhook signing secret",
        "tags": [
          "Webhooks"
        ],
        "x-admin": true,
        "x-scopes": [
          "webhooks:manage"
        ]
      }
    },
    "/v1/webhooks/{endpoint_id}/test": {
      "post": {
        "description": "Send a `ping` event to this endpoint only. Counts as one call.",
        "operationId": "webhooks.test",
        "parameters": [
          {
            "in": "path",
            "name": "endpoint_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Endpoint Id",
              "type": "string"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TestSentOut"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "No such endpoint (ERR_NOT_FOUND).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "Send a test event",
        "tags": [
          "Webhooks"
        ],
        "x-admin": true,
        "x-scopes": [
          "webhooks:manage"
        ]
      }
    },
    "/v1/work-orders": {
      "get": {
        "description": "Work orders newest first, or, with `updated_since`, everything changed\nsince then, oldest first. Page with `cursor`. Readable from a production\nrole up.",
        "operationId": "workOrders.list",
        "parameters": [
          {
            "description": "Only this job's work orders.",
            "in": "query",
            "name": "job_id",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "format": "uuid",
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only this job's work orders.",
              "title": "Job Id"
            }
          },
          {
            "description": "Only work orders at this step.",
            "in": "query",
            "name": "status_id",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "format": "uuid",
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only work orders at this step.",
              "title": "Status Id"
            }
          },
          {
            "description": "Only this type (Prep, Production, Install, ...).",
            "in": "query",
            "name": "type_id",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "format": "uuid",
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only this type (Prep, Production, Install, ...).",
              "title": "Type Id"
            }
          },
          {
            "description": "Only work orders changed at or after this time, oldest first. How to keep another system in step.",
            "in": "query",
            "name": "updated_since",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "format": "date-time",
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only work orders changed at or after this time, oldest first. How to keep another system in step.",
              "title": "Updated Since"
            }
          },
          {
            "description": "sections: add each work order's steps.",
            "in": "query",
            "name": "include",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "sections: add each work order's steps.",
              "title": "Include"
            }
          },
          {
            "description": "From the previous page's next_cursor.",
            "in": "query",
            "name": "cursor",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "From the previous page's next_cursor.",
              "title": "Cursor"
            }
          },
          {
            "description": "Page size, 1 to 200. Default 50.",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "maximum": 200,
                  "minimum": 1,
                  "type": "integer"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Page size, 1 to 200. Default 50.",
              "title": "Limit"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkOrderPage"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "List work orders",
        "tags": [
          "Work orders"
        ],
        "x-scopes": [
          "work_orders:read"
        ]
      },
      "post": {
        "description": "Create a work order on a job from a type and, optionally, a template.\n\nIt gets the template's steps with their departments and starts at the\ntemplate's first step, the same as a work order made in the app. An\nopen opportunity can carry only a Prep work order. Needs an office role\nor above.",
        "operationId": "workOrders.create",
        "parameters": [
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WorkOrderCreateIn"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkOrderOut"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "The job, type, template or an assignee is not in this account (ERR_NOT_FOUND).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "Create a work order",
        "tags": [
          "Work orders"
        ],
        "x-scopes": [
          "work_orders:write"
        ]
      }
    },
    "/v1/work-orders/{work_order_id}": {
      "get": {
        "description": "One work order with its steps. A step's status id is what\n`POST /v1/work-orders/{id}/status` takes.",
        "operationId": "workOrders.get",
        "parameters": [
          {
            "in": "path",
            "name": "work_order_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Work Order Id",
              "type": "string"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkOrderOut"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "No such work order in this account (ERR_NOT_FOUND).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "Get a work order",
        "tags": [
          "Work orders"
        ],
        "x-scopes": [
          "work_orders:read"
        ]
      },
      "patch": {
        "description": "Change the name, due date, priority or assignees. Only the fields you\nsend change. Needs an office role or above.",
        "operationId": "workOrders.update",
        "parameters": [
          {
            "in": "path",
            "name": "work_order_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Work Order Id",
              "type": "string"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WorkOrderUpdateIn"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkOrderOut"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "No such work order in this account (ERR_NOT_FOUND).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Validation (ERR_VALIDATION, ERR_IDEMPOTENCY_*).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "Update a work order",
        "tags": [
          "Work orders"
        ],
        "x-scopes": [
          "work_orders:write"
        ]
      }
    },
    "/v1/work-orders/{work_order_id}/status": {
      "post": {
        "description": "Move the work order to one of its own steps.\n\nThe move is the app's own: it is recorded in the work order's history\nas the acting user, the people following the job are notified, a\ncompleted step stamps `completed_at`, and the capacity board follows.\nNeeds an office role or above.",
        "operationId": "workOrders.setStatus",
        "parameters": [
          {
            "in": "path",
            "name": "work_order_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Work Order Id",
              "type": "string"
            }
          },
          {
            "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A unique string per submission - a UUID, or your own record id. Required on every POST. If the same value arrives twice with the same body we return the first response instead of creating a second record, which is what stops a timeout or an automatic retry from putting the same customer in the pipeline twice.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WorkOrderStatusIn"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkOrderOut"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Bad request (ERR_TENANT_HEADER).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Missing or invalid credential (ERR_AUTH_*, ERR_ACTOR_INACTIVE, ERR_WRONG_ENVIRONMENT).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Monthly quota used up and no more can be billed (ERR_QUOTA_EXCEEDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Not allowed (ERR_SCOPE_MISSING, ERR_ROLE_REQUIRED, ERR_OAUTH_NOT_ALLOWED, ERR_NOT_ENTITLED, ERR_ACCOUNT_SUSPENDED).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "No such work order in this account (ERR_NOT_FOUND).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "The status is not one of this work order's steps (ERR_VALIDATION).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Rate limited (ERR_RATE_LIMITED); read Retry-After.",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            },
            "description": "Upstream failure (ERR_UPSTREAM).",
            "headers": {
              "X-RateLimit-Limit": {
                "description": "Calls per minute allowed.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Calls left before the limit.",
                "schema": {
                  "type": "string"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Seconds until the limit is fully restored.",
                "schema": {
                  "type": "string"
                }
              },
              "X-Request-Id": {
                "description": "Quote this to support.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "security": [
          {
            "API key": []
          },
          {
            "Account id": []
          },
          {
            "Bearer": []
          }
        ],
        "summary": "Move a work order to a step",
        "tags": [
          "Work orders"
        ],
        "x-scopes": [
          "work_orders:write"
        ]
      }
    }
  },
  "tags": [
    {
      "description": "Who you are connected as, and this month's usage.",
      "name": "Account"
    },
    {
      "description": "The account's own vocabulary: statuses, types, departments, custom fields, forms, users. Look ids up here before writing.",
      "name": "Meta"
    },
    {
      "description": "Create leads in the sales pipeline. The first-release route, kept as it was.",
      "name": "Leads"
    },
    {
      "description": "Leads, opportunities and jobs: one record through its whole life.",
      "name": "Jobs"
    },
    {
      "description": "The people on jobs.",
      "name": "Contacts"
    },
    {
      "description": "To-dos on jobs.",
      "name": "Tasks"
    },
    {
      "description": "Internal notes on a job's message thread.",
      "name": "Notes"
    },
    {
      "description": "Events: installs, site visits, meetings.",
      "name": "Calendar"
    },
    {
      "description": "Quotes, as drafts with sections and lines; send by email.",
      "name": "Estimates"
    },
    {
      "description": "Invoices, as drafts; send by email. Payments are read-only.",
      "name": "Invoices"
    },
    {
      "description": "Files on jobs, uploaded through signed URLs.",
      "name": "Files"
    },
    {
      "description": "Email a job's contacts through the account's connected mailbox.",
      "name": "Comms"
    },
    {
      "description": "Production work orders and their statuses.",
      "name": "Work orders"
    },
    {
      "description": "Materials, stock items and job bills of materials.",
      "name": "Materials"
    },
    {
      "description": "Vendors, purchase orders and receiving.",
      "name": "Purchasing"
    },
    {
      "description": "The product catalog.",
      "name": "Products"
    },
    {
      "description": "Time entries, read-only.",
      "name": "Time"
    },
    {
      "description": "Endpoints we deliver events to, and their delivery log.",
      "name": "Webhooks"
    }
  ],
  "webhooks": {
    "calendar_event.created": {
      "post": {
        "description": "Verify `WoodSystems-Signature: t=<unix>,v1=<hex>[,v1=<hex>]`: compute HMAC-SHA256 with the endpoint secret over `<t>.<raw body>`, compare in constant time to any `v1`, and reject when `t` is more than 300 seconds old. Treat `WoodSystems-Event-Id` as the idempotency key; retries carry `WoodSystems-Replay: true`. Answer any 2xx within 10 seconds. Failed deliveries are retried after 1m, 5m, 30m, 2h, 12h and 24h, then given up. An endpoint failing 20 times in a row over a day, or answering 410, is switched off and the account admins are told.",
        "operationId": "webhook.calendar_event.created",
        "parameters": [
          {
            "description": "t=<unix>,v1=<hex>; see the description.",
            "in": "header",
            "name": "WoodSystems-Signature",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The event type.",
            "in": "header",
            "name": "WoodSystems-Event",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Stable per event; use it to drop repeats.",
            "in": "header",
            "name": "WoodSystems-Event-Id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Stable per delivery to your endpoint.",
            "in": "header",
            "name": "WoodSystems-Delivery-Id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "1 for the first try.",
            "in": "header",
            "name": "WoodSystems-Attempt",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "true on retries.",
            "in": "header",
            "name": "WoodSystems-Replay",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "live or sandbox.",
            "in": "header",
            "name": "WoodSystems-Environment",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The prefix of your key, when the change came from it.",
            "in": "header",
            "name": "WoodSystems-Source-Key",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "api_version": "v1",
                "created_at": "2026-10-06T15:12:00Z",
                "data": {
                  "object": {
                    "all_day": true,
                    "end": "2026-11-18",
                    "id": "8f9a0b1c-2d3e-4f4a-9b5c-6d7e8f9a0b1c",
                    "job_id": "3f9a1c77-5e3b-4a02-9d8e-2c7b6a1f0e4d",
                    "start": "2026-11-16",
                    "title": "Install crew on site",
                    "updated_at": "2026-10-06T15:12:00Z"
                  },
                  "url": "https://api.woodsystems.com/v1/calendar/events/8f9a0b1c-2d3e-4f4a-9b5c-6d7e8f9a0b1c"
                },
                "id": "a0b1c2d3-e4f5-4a6b-8c7d-9e0f1a2b3c4d",
                "livemode": true,
                "object": "event",
                "source": {
                  "kind": "ui",
                  "user_id": "e1d2c3b4-a596-4877-8695-a4b3c2d1e0f9"
                },
                "tenant_id": "5c8d2e1f-3a4b-4c6d-8e9f-0a1b2c3d4e5f",
                "type": "calendar_event.created"
              },
              "schema": {
                "$ref": "#/components/schemas/WebhookEvent"
              }
            }
          },
          "required": true
        },
        "responses": {
          "2XX": {
            "description": "Received. Anything else is retried."
          }
        },
        "summary": "A calendar event was created.",
        "tags": [
          "Webhooks"
        ]
      }
    },
    "calendar_event.deleted": {
      "post": {
        "description": "Verify `WoodSystems-Signature: t=<unix>,v1=<hex>[,v1=<hex>]`: compute HMAC-SHA256 with the endpoint secret over `<t>.<raw body>`, compare in constant time to any `v1`, and reject when `t` is more than 300 seconds old. Treat `WoodSystems-Event-Id` as the idempotency key; retries carry `WoodSystems-Replay: true`. Answer any 2xx within 10 seconds. Failed deliveries are retried after 1m, 5m, 30m, 2h, 12h and 24h, then given up. An endpoint failing 20 times in a row over a day, or answering 410, is switched off and the account admins are told.",
        "operationId": "webhook.calendar_event.deleted",
        "parameters": [
          {
            "description": "t=<unix>,v1=<hex>; see the description.",
            "in": "header",
            "name": "WoodSystems-Signature",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The event type.",
            "in": "header",
            "name": "WoodSystems-Event",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Stable per event; use it to drop repeats.",
            "in": "header",
            "name": "WoodSystems-Event-Id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Stable per delivery to your endpoint.",
            "in": "header",
            "name": "WoodSystems-Delivery-Id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "1 for the first try.",
            "in": "header",
            "name": "WoodSystems-Attempt",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "true on retries.",
            "in": "header",
            "name": "WoodSystems-Replay",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "live or sandbox.",
            "in": "header",
            "name": "WoodSystems-Environment",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The prefix of your key, when the change came from it.",
            "in": "header",
            "name": "WoodSystems-Source-Key",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "api_version": "v1",
                "created_at": "2026-10-06T15:12:00Z",
                "data": {
                  "object": {
                    "all_day": true,
                    "end": "2026-11-18",
                    "id": "8f9a0b1c-2d3e-4f4a-9b5c-6d7e8f9a0b1c",
                    "job_id": "3f9a1c77-5e3b-4a02-9d8e-2c7b6a1f0e4d",
                    "start": "2026-11-16",
                    "title": "Install crew on site",
                    "updated_at": "2026-10-06T15:12:00Z"
                  }
                },
                "id": "a0b1c2d3-e4f5-4a6b-8c7d-9e0f1a2b3c4d",
                "livemode": true,
                "object": "event",
                "source": {
                  "kind": "ui",
                  "user_id": "e1d2c3b4-a596-4877-8695-a4b3c2d1e0f9"
                },
                "tenant_id": "5c8d2e1f-3a4b-4c6d-8e9f-0a1b2c3d4e5f",
                "type": "calendar_event.deleted"
              },
              "schema": {
                "$ref": "#/components/schemas/WebhookEvent"
              }
            }
          },
          "required": true
        },
        "responses": {
          "2XX": {
            "description": "Received. Anything else is retried."
          }
        },
        "summary": "A calendar event was deleted.",
        "tags": [
          "Webhooks"
        ]
      }
    },
    "calendar_event.updated": {
      "post": {
        "description": "Verify `WoodSystems-Signature: t=<unix>,v1=<hex>[,v1=<hex>]`: compute HMAC-SHA256 with the endpoint secret over `<t>.<raw body>`, compare in constant time to any `v1`, and reject when `t` is more than 300 seconds old. Treat `WoodSystems-Event-Id` as the idempotency key; retries carry `WoodSystems-Replay: true`. Answer any 2xx within 10 seconds. Failed deliveries are retried after 1m, 5m, 30m, 2h, 12h and 24h, then given up. An endpoint failing 20 times in a row over a day, or answering 410, is switched off and the account admins are told.",
        "operationId": "webhook.calendar_event.updated",
        "parameters": [
          {
            "description": "t=<unix>,v1=<hex>; see the description.",
            "in": "header",
            "name": "WoodSystems-Signature",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The event type.",
            "in": "header",
            "name": "WoodSystems-Event",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Stable per event; use it to drop repeats.",
            "in": "header",
            "name": "WoodSystems-Event-Id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Stable per delivery to your endpoint.",
            "in": "header",
            "name": "WoodSystems-Delivery-Id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "1 for the first try.",
            "in": "header",
            "name": "WoodSystems-Attempt",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "true on retries.",
            "in": "header",
            "name": "WoodSystems-Replay",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "live or sandbox.",
            "in": "header",
            "name": "WoodSystems-Environment",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The prefix of your key, when the change came from it.",
            "in": "header",
            "name": "WoodSystems-Source-Key",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "api_version": "v1",
                "created_at": "2026-10-06T15:12:00Z",
                "data": {
                  "object": {
                    "all_day": true,
                    "end": "2026-11-18",
                    "id": "8f9a0b1c-2d3e-4f4a-9b5c-6d7e8f9a0b1c",
                    "job_id": "3f9a1c77-5e3b-4a02-9d8e-2c7b6a1f0e4d",
                    "start": "2026-11-16",
                    "title": "Install crew on site",
                    "updated_at": "2026-10-06T15:12:00Z"
                  },
                  "url": "https://api.woodsystems.com/v1/calendar/events/8f9a0b1c-2d3e-4f4a-9b5c-6d7e8f9a0b1c"
                },
                "id": "a0b1c2d3-e4f5-4a6b-8c7d-9e0f1a2b3c4d",
                "livemode": true,
                "object": "event",
                "source": {
                  "kind": "ui",
                  "user_id": "e1d2c3b4-a596-4877-8695-a4b3c2d1e0f9"
                },
                "tenant_id": "5c8d2e1f-3a4b-4c6d-8e9f-0a1b2c3d4e5f",
                "type": "calendar_event.updated"
              },
              "schema": {
                "$ref": "#/components/schemas/WebhookEvent"
              }
            }
          },
          "required": true
        },
        "responses": {
          "2XX": {
            "description": "Received. Anything else is retried."
          }
        },
        "summary": "A calendar event was moved or changed.",
        "tags": [
          "Webhooks"
        ]
      }
    },
    "contact.created": {
      "post": {
        "description": "Verify `WoodSystems-Signature: t=<unix>,v1=<hex>[,v1=<hex>]`: compute HMAC-SHA256 with the endpoint secret over `<t>.<raw body>`, compare in constant time to any `v1`, and reject when `t` is more than 300 seconds old. Treat `WoodSystems-Event-Id` as the idempotency key; retries carry `WoodSystems-Replay: true`. Answer any 2xx within 10 seconds. Failed deliveries are retried after 1m, 5m, 30m, 2h, 12h and 24h, then given up. An endpoint failing 20 times in a row over a day, or answering 410, is switched off and the account admins are told.",
        "operationId": "webhook.contact.created",
        "parameters": [
          {
            "description": "t=<unix>,v1=<hex>; see the description.",
            "in": "header",
            "name": "WoodSystems-Signature",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The event type.",
            "in": "header",
            "name": "WoodSystems-Event",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Stable per event; use it to drop repeats.",
            "in": "header",
            "name": "WoodSystems-Event-Id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Stable per delivery to your endpoint.",
            "in": "header",
            "name": "WoodSystems-Delivery-Id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "1 for the first try.",
            "in": "header",
            "name": "WoodSystems-Attempt",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "true on retries.",
            "in": "header",
            "name": "WoodSystems-Replay",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "live or sandbox.",
            "in": "header",
            "name": "WoodSystems-Environment",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The prefix of your key, when the change came from it.",
            "in": "header",
            "name": "WoodSystems-Source-Key",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "api_version": "v1",
                "created_at": "2026-10-06T15:12:00Z",
                "data": {
                  "object": {
                    "email": "dana.whitfield@example.com",
                    "first_name": "Dana",
                    "id": "b2d4e6f8-1a3c-5e7b-9d0f-2a4c6e8b0d1f",
                    "job_id": "3f9a1c77-5e3b-4a02-9d8e-2c7b6a1f0e4d",
                    "last_name": "Whitfield"
                  },
                  "url": "https://api.woodsystems.com/v1/contacts/b2d4e6f8-1a3c-5e7b-9d0f-2a4c6e8b0d1f"
                },
                "id": "a0b1c2d3-e4f5-4a6b-8c7d-9e0f1a2b3c4d",
                "livemode": true,
                "object": "event",
                "source": {
                  "kind": "ui",
                  "user_id": "e1d2c3b4-a596-4877-8695-a4b3c2d1e0f9"
                },
                "tenant_id": "5c8d2e1f-3a4b-4c6d-8e9f-0a1b2c3d4e5f",
                "type": "contact.created"
              },
              "schema": {
                "$ref": "#/components/schemas/WebhookEvent"
              }
            }
          },
          "required": true
        },
        "responses": {
          "2XX": {
            "description": "Received. Anything else is retried."
          }
        },
        "summary": "A new contact was added to a job.",
        "tags": [
          "Webhooks"
        ]
      }
    },
    "estimate.created": {
      "post": {
        "description": "Verify `WoodSystems-Signature: t=<unix>,v1=<hex>[,v1=<hex>]`: compute HMAC-SHA256 with the endpoint secret over `<t>.<raw body>`, compare in constant time to any `v1`, and reject when `t` is more than 300 seconds old. Treat `WoodSystems-Event-Id` as the idempotency key; retries carry `WoodSystems-Replay: true`. Answer any 2xx within 10 seconds. Failed deliveries are retried after 1m, 5m, 30m, 2h, 12h and 24h, then given up. An endpoint failing 20 times in a row over a day, or answering 410, is switched off and the account admins are told.",
        "operationId": "webhook.estimate.created",
        "parameters": [
          {
            "description": "t=<unix>,v1=<hex>; see the description.",
            "in": "header",
            "name": "WoodSystems-Signature",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The event type.",
            "in": "header",
            "name": "WoodSystems-Event",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Stable per event; use it to drop repeats.",
            "in": "header",
            "name": "WoodSystems-Event-Id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Stable per delivery to your endpoint.",
            "in": "header",
            "name": "WoodSystems-Delivery-Id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "1 for the first try.",
            "in": "header",
            "name": "WoodSystems-Attempt",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "true on retries.",
            "in": "header",
            "name": "WoodSystems-Replay",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "live or sandbox.",
            "in": "header",
            "name": "WoodSystems-Environment",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The prefix of your key, when the change came from it.",
            "in": "header",
            "name": "WoodSystems-Source-Key",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "api_version": "v1",
                "created_at": "2026-10-06T15:12:00Z",
                "data": {
                  "object": {
                    "id": "0c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
                    "job_id": "3f9a1c77-5e3b-4a02-9d8e-2c7b6a1f0e4d",
                    "name": "Kitchen cabinets",
                    "reference": "E60",
                    "status": {
                      "id": "1e2f3a4b-5c6d-4e7f-8a9b-0c1d2e3f4a5b",
                      "name": "Sent"
                    },
                    "updated_at": "2026-10-06T15:12:00Z"
                  },
                  "url": "https://api.woodsystems.com/v1/estimates/0c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f"
                },
                "id": "a0b1c2d3-e4f5-4a6b-8c7d-9e0f1a2b3c4d",
                "livemode": true,
                "object": "event",
                "source": {
                  "kind": "ui",
                  "user_id": "e1d2c3b4-a596-4877-8695-a4b3c2d1e0f9"
                },
                "tenant_id": "5c8d2e1f-3a4b-4c6d-8e9f-0a1b2c3d4e5f",
                "type": "estimate.created"
              },
              "schema": {
                "$ref": "#/components/schemas/WebhookEvent"
              }
            }
          },
          "required": true
        },
        "responses": {
          "2XX": {
            "description": "Received. Anything else is retried."
          }
        },
        "summary": "An estimate was created.",
        "tags": [
          "Webhooks"
        ]
      }
    },
    "estimate.declined": {
      "post": {
        "description": "Verify `WoodSystems-Signature: t=<unix>,v1=<hex>[,v1=<hex>]`: compute HMAC-SHA256 with the endpoint secret over `<t>.<raw body>`, compare in constant time to any `v1`, and reject when `t` is more than 300 seconds old. Treat `WoodSystems-Event-Id` as the idempotency key; retries carry `WoodSystems-Replay: true`. Answer any 2xx within 10 seconds. Failed deliveries are retried after 1m, 5m, 30m, 2h, 12h and 24h, then given up. An endpoint failing 20 times in a row over a day, or answering 410, is switched off and the account admins are told.",
        "operationId": "webhook.estimate.declined",
        "parameters": [
          {
            "description": "t=<unix>,v1=<hex>; see the description.",
            "in": "header",
            "name": "WoodSystems-Signature",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The event type.",
            "in": "header",
            "name": "WoodSystems-Event",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Stable per event; use it to drop repeats.",
            "in": "header",
            "name": "WoodSystems-Event-Id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Stable per delivery to your endpoint.",
            "in": "header",
            "name": "WoodSystems-Delivery-Id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "1 for the first try.",
            "in": "header",
            "name": "WoodSystems-Attempt",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "true on retries.",
            "in": "header",
            "name": "WoodSystems-Replay",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "live or sandbox.",
            "in": "header",
            "name": "WoodSystems-Environment",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The prefix of your key, when the change came from it.",
            "in": "header",
            "name": "WoodSystems-Source-Key",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "api_version": "v1",
                "created_at": "2026-10-06T15:12:00Z",
                "data": {
                  "object": {
                    "id": "0c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
                    "job_id": "3f9a1c77-5e3b-4a02-9d8e-2c7b6a1f0e4d",
                    "name": "Kitchen cabinets",
                    "reference": "E60",
                    "status": {
                      "id": "1e2f3a4b-5c6d-4e7f-8a9b-0c1d2e3f4a5b",
                      "name": "Sent"
                    },
                    "updated_at": "2026-10-06T15:12:00Z"
                  },
                  "url": "https://api.woodsystems.com/v1/estimates/0c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f"
                },
                "id": "a0b1c2d3-e4f5-4a6b-8c7d-9e0f1a2b3c4d",
                "livemode": true,
                "object": "event",
                "source": {
                  "kind": "ui",
                  "user_id": "e1d2c3b4-a596-4877-8695-a4b3c2d1e0f9"
                },
                "tenant_id": "5c8d2e1f-3a4b-4c6d-8e9f-0a1b2c3d4e5f",
                "type": "estimate.declined"
              },
              "schema": {
                "$ref": "#/components/schemas/WebhookEvent"
              }
            }
          },
          "required": true
        },
        "responses": {
          "2XX": {
            "description": "Received. Anything else is retried."
          }
        },
        "summary": "A customer declined an estimate.",
        "tags": [
          "Webhooks"
        ]
      }
    },
    "estimate.sent": {
      "post": {
        "description": "Verify `WoodSystems-Signature: t=<unix>,v1=<hex>[,v1=<hex>]`: compute HMAC-SHA256 with the endpoint secret over `<t>.<raw body>`, compare in constant time to any `v1`, and reject when `t` is more than 300 seconds old. Treat `WoodSystems-Event-Id` as the idempotency key; retries carry `WoodSystems-Replay: true`. Answer any 2xx within 10 seconds. Failed deliveries are retried after 1m, 5m, 30m, 2h, 12h and 24h, then given up. An endpoint failing 20 times in a row over a day, or answering 410, is switched off and the account admins are told.",
        "operationId": "webhook.estimate.sent",
        "parameters": [
          {
            "description": "t=<unix>,v1=<hex>; see the description.",
            "in": "header",
            "name": "WoodSystems-Signature",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The event type.",
            "in": "header",
            "name": "WoodSystems-Event",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Stable per event; use it to drop repeats.",
            "in": "header",
            "name": "WoodSystems-Event-Id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Stable per delivery to your endpoint.",
            "in": "header",
            "name": "WoodSystems-Delivery-Id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "1 for the first try.",
            "in": "header",
            "name": "WoodSystems-Attempt",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "true on retries.",
            "in": "header",
            "name": "WoodSystems-Replay",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "live or sandbox.",
            "in": "header",
            "name": "WoodSystems-Environment",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The prefix of your key, when the change came from it.",
            "in": "header",
            "name": "WoodSystems-Source-Key",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "api_version": "v1",
                "created_at": "2026-10-06T15:12:00Z",
                "data": {
                  "object": {
                    "id": "0c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
                    "job_id": "3f9a1c77-5e3b-4a02-9d8e-2c7b6a1f0e4d",
                    "name": "Kitchen cabinets",
                    "reference": "E60",
                    "status": {
                      "id": "1e2f3a4b-5c6d-4e7f-8a9b-0c1d2e3f4a5b",
                      "name": "Sent"
                    },
                    "updated_at": "2026-10-06T15:12:00Z"
                  },
                  "url": "https://api.woodsystems.com/v1/estimates/0c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f"
                },
                "id": "a0b1c2d3-e4f5-4a6b-8c7d-9e0f1a2b3c4d",
                "livemode": true,
                "object": "event",
                "source": {
                  "kind": "ui",
                  "user_id": "e1d2c3b4-a596-4877-8695-a4b3c2d1e0f9"
                },
                "tenant_id": "5c8d2e1f-3a4b-4c6d-8e9f-0a1b2c3d4e5f",
                "type": "estimate.sent"
              },
              "schema": {
                "$ref": "#/components/schemas/WebhookEvent"
              }
            }
          },
          "required": true
        },
        "responses": {
          "2XX": {
            "description": "Received. Anything else is retried."
          }
        },
        "summary": "An estimate was emailed to a customer.",
        "tags": [
          "Webhooks"
        ]
      }
    },
    "estimate.signed": {
      "post": {
        "description": "Verify `WoodSystems-Signature: t=<unix>,v1=<hex>[,v1=<hex>]`: compute HMAC-SHA256 with the endpoint secret over `<t>.<raw body>`, compare in constant time to any `v1`, and reject when `t` is more than 300 seconds old. Treat `WoodSystems-Event-Id` as the idempotency key; retries carry `WoodSystems-Replay: true`. Answer any 2xx within 10 seconds. Failed deliveries are retried after 1m, 5m, 30m, 2h, 12h and 24h, then given up. An endpoint failing 20 times in a row over a day, or answering 410, is switched off and the account admins are told.",
        "operationId": "webhook.estimate.signed",
        "parameters": [
          {
            "description": "t=<unix>,v1=<hex>; see the description.",
            "in": "header",
            "name": "WoodSystems-Signature",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The event type.",
            "in": "header",
            "name": "WoodSystems-Event",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Stable per event; use it to drop repeats.",
            "in": "header",
            "name": "WoodSystems-Event-Id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Stable per delivery to your endpoint.",
            "in": "header",
            "name": "WoodSystems-Delivery-Id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "1 for the first try.",
            "in": "header",
            "name": "WoodSystems-Attempt",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "true on retries.",
            "in": "header",
            "name": "WoodSystems-Replay",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "live or sandbox.",
            "in": "header",
            "name": "WoodSystems-Environment",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The prefix of your key, when the change came from it.",
            "in": "header",
            "name": "WoodSystems-Source-Key",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "api_version": "v1",
                "created_at": "2026-10-06T15:12:00Z",
                "data": {
                  "object": {
                    "id": "0c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
                    "job_id": "3f9a1c77-5e3b-4a02-9d8e-2c7b6a1f0e4d",
                    "name": "Kitchen cabinets",
                    "reference": "E60",
                    "status": {
                      "id": "1e2f3a4b-5c6d-4e7f-8a9b-0c1d2e3f4a5b",
                      "name": "Sent"
                    },
                    "updated_at": "2026-10-06T15:12:00Z"
                  },
                  "url": "https://api.woodsystems.com/v1/estimates/0c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f"
                },
                "id": "a0b1c2d3-e4f5-4a6b-8c7d-9e0f1a2b3c4d",
                "livemode": true,
                "object": "event",
                "source": {
                  "kind": "ui",
                  "user_id": "e1d2c3b4-a596-4877-8695-a4b3c2d1e0f9"
                },
                "tenant_id": "5c8d2e1f-3a4b-4c6d-8e9f-0a1b2c3d4e5f",
                "type": "estimate.signed"
              },
              "schema": {
                "$ref": "#/components/schemas/WebhookEvent"
              }
            }
          },
          "required": true
        },
        "responses": {
          "2XX": {
            "description": "Received. Anything else is retried."
          }
        },
        "summary": "A customer signed or accepted an estimate.",
        "tags": [
          "Webhooks"
        ]
      }
    },
    "estimate.status_changed": {
      "post": {
        "description": "Verify `WoodSystems-Signature: t=<unix>,v1=<hex>[,v1=<hex>]`: compute HMAC-SHA256 with the endpoint secret over `<t>.<raw body>`, compare in constant time to any `v1`, and reject when `t` is more than 300 seconds old. Treat `WoodSystems-Event-Id` as the idempotency key; retries carry `WoodSystems-Replay: true`. Answer any 2xx within 10 seconds. Failed deliveries are retried after 1m, 5m, 30m, 2h, 12h and 24h, then given up. An endpoint failing 20 times in a row over a day, or answering 410, is switched off and the account admins are told.",
        "operationId": "webhook.estimate.status_changed",
        "parameters": [
          {
            "description": "t=<unix>,v1=<hex>; see the description.",
            "in": "header",
            "name": "WoodSystems-Signature",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The event type.",
            "in": "header",
            "name": "WoodSystems-Event",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Stable per event; use it to drop repeats.",
            "in": "header",
            "name": "WoodSystems-Event-Id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Stable per delivery to your endpoint.",
            "in": "header",
            "name": "WoodSystems-Delivery-Id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "1 for the first try.",
            "in": "header",
            "name": "WoodSystems-Attempt",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "true on retries.",
            "in": "header",
            "name": "WoodSystems-Replay",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "live or sandbox.",
            "in": "header",
            "name": "WoodSystems-Environment",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The prefix of your key, when the change came from it.",
            "in": "header",
            "name": "WoodSystems-Source-Key",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "api_version": "v1",
                "created_at": "2026-10-06T15:12:00Z",
                "data": {
                  "object": {
                    "id": "0c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
                    "job_id": "3f9a1c77-5e3b-4a02-9d8e-2c7b6a1f0e4d",
                    "name": "Kitchen cabinets",
                    "reference": "E60",
                    "status": {
                      "id": "1e2f3a4b-5c6d-4e7f-8a9b-0c1d2e3f4a5b",
                      "name": "Sent"
                    },
                    "updated_at": "2026-10-06T15:12:00Z"
                  },
                  "previous_attributes": {
                    "status": {
                      "id": "9b8a7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
                      "name": "Backlog"
                    }
                  },
                  "url": "https://api.woodsystems.com/v1/estimates/0c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f"
                },
                "id": "a0b1c2d3-e4f5-4a6b-8c7d-9e0f1a2b3c4d",
                "livemode": true,
                "object": "event",
                "source": {
                  "kind": "ui",
                  "user_id": "e1d2c3b4-a596-4877-8695-a4b3c2d1e0f9"
                },
                "tenant_id": "5c8d2e1f-3a4b-4c6d-8e9f-0a1b2c3d4e5f",
                "type": "estimate.status_changed"
              },
              "schema": {
                "$ref": "#/components/schemas/WebhookEvent"
              }
            }
          },
          "required": true
        },
        "responses": {
          "2XX": {
            "description": "Received. Anything else is retried."
          }
        },
        "summary": "An estimate moved to another status.",
        "tags": [
          "Webhooks"
        ]
      }
    },
    "file.uploaded": {
      "post": {
        "description": "Verify `WoodSystems-Signature: t=<unix>,v1=<hex>[,v1=<hex>]`: compute HMAC-SHA256 with the endpoint secret over `<t>.<raw body>`, compare in constant time to any `v1`, and reject when `t` is more than 300 seconds old. Treat `WoodSystems-Event-Id` as the idempotency key; retries carry `WoodSystems-Replay: true`. Answer any 2xx within 10 seconds. Failed deliveries are retried after 1m, 5m, 30m, 2h, 12h and 24h, then given up. An endpoint failing 20 times in a row over a day, or answering 410, is switched off and the account admins are told.",
        "operationId": "webhook.file.uploaded",
        "parameters": [
          {
            "description": "t=<unix>,v1=<hex>; see the description.",
            "in": "header",
            "name": "WoodSystems-Signature",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The event type.",
            "in": "header",
            "name": "WoodSystems-Event",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Stable per event; use it to drop repeats.",
            "in": "header",
            "name": "WoodSystems-Event-Id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Stable per delivery to your endpoint.",
            "in": "header",
            "name": "WoodSystems-Delivery-Id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "1 for the first try.",
            "in": "header",
            "name": "WoodSystems-Attempt",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "true on retries.",
            "in": "header",
            "name": "WoodSystems-Replay",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "live or sandbox.",
            "in": "header",
            "name": "WoodSystems-Environment",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The prefix of your key, when the change came from it.",
            "in": "header",
            "name": "WoodSystems-Source-Key",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "api_version": "v1",
                "created_at": "2026-10-06T15:12:00Z",
                "data": {
                  "object": {
                    "content_type": "application/pdf",
                    "id": "3e4f5a6b-7c8d-4e9f-8a0b-1c2d3e4f5a6b",
                    "job_id": "3f9a1c77-5e3b-4a02-9d8e-2c7b6a1f0e4d",
                    "name": "site-measure.pdf",
                    "size_bytes": 482113
                  },
                  "url": "https://api.woodsystems.com/v1/files/3e4f5a6b-7c8d-4e9f-8a0b-1c2d3e4f5a6b"
                },
                "id": "a0b1c2d3-e4f5-4a6b-8c7d-9e0f1a2b3c4d",
                "livemode": true,
                "object": "event",
                "source": {
                  "kind": "ui",
                  "user_id": "e1d2c3b4-a596-4877-8695-a4b3c2d1e0f9"
                },
                "tenant_id": "5c8d2e1f-3a4b-4c6d-8e9f-0a1b2c3d4e5f",
                "type": "file.uploaded"
              },
              "schema": {
                "$ref": "#/components/schemas/WebhookEvent"
              }
            }
          },
          "required": true
        },
        "responses": {
          "2XX": {
            "description": "Received. Anything else is retried."
          }
        },
        "summary": "A file was uploaded to a job.",
        "tags": [
          "Webhooks"
        ]
      }
    },
    "invoice.created": {
      "post": {
        "description": "Verify `WoodSystems-Signature: t=<unix>,v1=<hex>[,v1=<hex>]`: compute HMAC-SHA256 with the endpoint secret over `<t>.<raw body>`, compare in constant time to any `v1`, and reject when `t` is more than 300 seconds old. Treat `WoodSystems-Event-Id` as the idempotency key; retries carry `WoodSystems-Replay: true`. Answer any 2xx within 10 seconds. Failed deliveries are retried after 1m, 5m, 30m, 2h, 12h and 24h, then given up. An endpoint failing 20 times in a row over a day, or answering 410, is switched off and the account admins are told.",
        "operationId": "webhook.invoice.created",
        "parameters": [
          {
            "description": "t=<unix>,v1=<hex>; see the description.",
            "in": "header",
            "name": "WoodSystems-Signature",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The event type.",
            "in": "header",
            "name": "WoodSystems-Event",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Stable per event; use it to drop repeats.",
            "in": "header",
            "name": "WoodSystems-Event-Id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Stable per delivery to your endpoint.",
            "in": "header",
            "name": "WoodSystems-Delivery-Id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "1 for the first try.",
            "in": "header",
            "name": "WoodSystems-Attempt",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "true on retries.",
            "in": "header",
            "name": "WoodSystems-Replay",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "live or sandbox.",
            "in": "header",
            "name": "WoodSystems-Environment",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The prefix of your key, when the change came from it.",
            "in": "header",
            "name": "WoodSystems-Source-Key",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "api_version": "v1",
                "created_at": "2026-10-06T15:12:00Z",
                "data": {
                  "object": {
                    "id": "2f3a4b5c-6d7e-4f8a-9b0c-1d2e3f4a5b6c",
                    "job_id": "3f9a1c77-5e3b-4a02-9d8e-2c7b6a1f0e4d",
                    "name": "Deposit",
                    "reference": "I41",
                    "status": {
                      "id": "3a4b5c6d-7e8f-4a9b-8c0d-1e2f3a4b5c6d",
                      "name": "Open"
                    },
                    "updated_at": "2026-10-06T15:12:00Z"
                  },
                  "url": "https://api.woodsystems.com/v1/invoices/2f3a4b5c-6d7e-4f8a-9b0c-1d2e3f4a5b6c"
                },
                "id": "a0b1c2d3-e4f5-4a6b-8c7d-9e0f1a2b3c4d",
                "livemode": true,
                "object": "event",
                "source": {
                  "kind": "ui",
                  "user_id": "e1d2c3b4-a596-4877-8695-a4b3c2d1e0f9"
                },
                "tenant_id": "5c8d2e1f-3a4b-4c6d-8e9f-0a1b2c3d4e5f",
                "type": "invoice.created"
              },
              "schema": {
                "$ref": "#/components/schemas/WebhookEvent"
              }
            }
          },
          "required": true
        },
        "responses": {
          "2XX": {
            "description": "Received. Anything else is retried."
          }
        },
        "summary": "An invoice was created, by hand or from a payment schedule.",
        "tags": [
          "Webhooks"
        ]
      }
    },
    "invoice.sent": {
      "post": {
        "description": "Verify `WoodSystems-Signature: t=<unix>,v1=<hex>[,v1=<hex>]`: compute HMAC-SHA256 with the endpoint secret over `<t>.<raw body>`, compare in constant time to any `v1`, and reject when `t` is more than 300 seconds old. Treat `WoodSystems-Event-Id` as the idempotency key; retries carry `WoodSystems-Replay: true`. Answer any 2xx within 10 seconds. Failed deliveries are retried after 1m, 5m, 30m, 2h, 12h and 24h, then given up. An endpoint failing 20 times in a row over a day, or answering 410, is switched off and the account admins are told.",
        "operationId": "webhook.invoice.sent",
        "parameters": [
          {
            "description": "t=<unix>,v1=<hex>; see the description.",
            "in": "header",
            "name": "WoodSystems-Signature",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The event type.",
            "in": "header",
            "name": "WoodSystems-Event",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Stable per event; use it to drop repeats.",
            "in": "header",
            "name": "WoodSystems-Event-Id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Stable per delivery to your endpoint.",
            "in": "header",
            "name": "WoodSystems-Delivery-Id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "1 for the first try.",
            "in": "header",
            "name": "WoodSystems-Attempt",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "true on retries.",
            "in": "header",
            "name": "WoodSystems-Replay",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "live or sandbox.",
            "in": "header",
            "name": "WoodSystems-Environment",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The prefix of your key, when the change came from it.",
            "in": "header",
            "name": "WoodSystems-Source-Key",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "api_version": "v1",
                "created_at": "2026-10-06T15:12:00Z",
                "data": {
                  "object": {
                    "id": "2f3a4b5c-6d7e-4f8a-9b0c-1d2e3f4a5b6c",
                    "job_id": "3f9a1c77-5e3b-4a02-9d8e-2c7b6a1f0e4d",
                    "name": "Deposit",
                    "reference": "I41",
                    "status": {
                      "id": "3a4b5c6d-7e8f-4a9b-8c0d-1e2f3a4b5c6d",
                      "name": "Open"
                    },
                    "updated_at": "2026-10-06T15:12:00Z"
                  },
                  "url": "https://api.woodsystems.com/v1/invoices/2f3a4b5c-6d7e-4f8a-9b0c-1d2e3f4a5b6c"
                },
                "id": "a0b1c2d3-e4f5-4a6b-8c7d-9e0f1a2b3c4d",
                "livemode": true,
                "object": "event",
                "source": {
                  "kind": "ui",
                  "user_id": "e1d2c3b4-a596-4877-8695-a4b3c2d1e0f9"
                },
                "tenant_id": "5c8d2e1f-3a4b-4c6d-8e9f-0a1b2c3d4e5f",
                "type": "invoice.sent"
              },
              "schema": {
                "$ref": "#/components/schemas/WebhookEvent"
              }
            }
          },
          "required": true
        },
        "responses": {
          "2XX": {
            "description": "Received. Anything else is retried."
          }
        },
        "summary": "An invoice was emailed to a customer.",
        "tags": [
          "Webhooks"
        ]
      }
    },
    "invoice.status_changed": {
      "post": {
        "description": "Verify `WoodSystems-Signature: t=<unix>,v1=<hex>[,v1=<hex>]`: compute HMAC-SHA256 with the endpoint secret over `<t>.<raw body>`, compare in constant time to any `v1`, and reject when `t` is more than 300 seconds old. Treat `WoodSystems-Event-Id` as the idempotency key; retries carry `WoodSystems-Replay: true`. Answer any 2xx within 10 seconds. Failed deliveries are retried after 1m, 5m, 30m, 2h, 12h and 24h, then given up. An endpoint failing 20 times in a row over a day, or answering 410, is switched off and the account admins are told.",
        "operationId": "webhook.invoice.status_changed",
        "parameters": [
          {
            "description": "t=<unix>,v1=<hex>; see the description.",
            "in": "header",
            "name": "WoodSystems-Signature",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The event type.",
            "in": "header",
            "name": "WoodSystems-Event",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Stable per event; use it to drop repeats.",
            "in": "header",
            "name": "WoodSystems-Event-Id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Stable per delivery to your endpoint.",
            "in": "header",
            "name": "WoodSystems-Delivery-Id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "1 for the first try.",
            "in": "header",
            "name": "WoodSystems-Attempt",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "true on retries.",
            "in": "header",
            "name": "WoodSystems-Replay",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "live or sandbox.",
            "in": "header",
            "name": "WoodSystems-Environment",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The prefix of your key, when the change came from it.",
            "in": "header",
            "name": "WoodSystems-Source-Key",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "api_version": "v1",
                "created_at": "2026-10-06T15:12:00Z",
                "data": {
                  "object": {
                    "id": "2f3a4b5c-6d7e-4f8a-9b0c-1d2e3f4a5b6c",
                    "job_id": "3f9a1c77-5e3b-4a02-9d8e-2c7b6a1f0e4d",
                    "name": "Deposit",
                    "reference": "I41",
                    "status": {
                      "id": "3a4b5c6d-7e8f-4a9b-8c0d-1e2f3a4b5c6d",
                      "name": "Open"
                    },
                    "updated_at": "2026-10-06T15:12:00Z"
                  },
                  "previous_attributes": {
                    "status": {
                      "id": "9b8a7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
                      "name": "Backlog"
                    }
                  },
                  "url": "https://api.woodsystems.com/v1/invoices/2f3a4b5c-6d7e-4f8a-9b0c-1d2e3f4a5b6c"
                },
                "id": "a0b1c2d3-e4f5-4a6b-8c7d-9e0f1a2b3c4d",
                "livemode": true,
                "object": "event",
                "source": {
                  "kind": "ui",
                  "user_id": "e1d2c3b4-a596-4877-8695-a4b3c2d1e0f9"
                },
                "tenant_id": "5c8d2e1f-3a4b-4c6d-8e9f-0a1b2c3d4e5f",
                "type": "invoice.status_changed"
              },
              "schema": {
                "$ref": "#/components/schemas/WebhookEvent"
              }
            }
          },
          "required": true
        },
        "responses": {
          "2XX": {
            "description": "Received. Anything else is retried."
          }
        },
        "summary": "An invoice moved to another status.",
        "tags": [
          "Webhooks"
        ]
      }
    },
    "job.converted": {
      "post": {
        "description": "Verify `WoodSystems-Signature: t=<unix>,v1=<hex>[,v1=<hex>]`: compute HMAC-SHA256 with the endpoint secret over `<t>.<raw body>`, compare in constant time to any `v1`, and reject when `t` is more than 300 seconds old. Treat `WoodSystems-Event-Id` as the idempotency key; retries carry `WoodSystems-Replay: true`. Answer any 2xx within 10 seconds. Failed deliveries are retried after 1m, 5m, 30m, 2h, 12h and 24h, then given up. An endpoint failing 20 times in a row over a day, or answering 410, is switched off and the account admins are told.",
        "operationId": "webhook.job.converted",
        "parameters": [
          {
            "description": "t=<unix>,v1=<hex>; see the description.",
            "in": "header",
            "name": "WoodSystems-Signature",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The event type.",
            "in": "header",
            "name": "WoodSystems-Event",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Stable per event; use it to drop repeats.",
            "in": "header",
            "name": "WoodSystems-Event-Id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Stable per delivery to your endpoint.",
            "in": "header",
            "name": "WoodSystems-Delivery-Id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "1 for the first try.",
            "in": "header",
            "name": "WoodSystems-Attempt",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "true on retries.",
            "in": "header",
            "name": "WoodSystems-Replay",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "live or sandbox.",
            "in": "header",
            "name": "WoodSystems-Environment",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The prefix of your key, when the change came from it.",
            "in": "header",
            "name": "WoodSystems-Source-Key",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "api_version": "v1",
                "created_at": "2026-10-06T15:12:00Z",
                "data": {
                  "object": {
                    "id": "3f9a1c77-5e3b-4a02-9d8e-2c7b6a1f0e4d",
                    "name": "Whitfield kitchen remodel",
                    "reference": "J1042",
                    "stage": "job",
                    "status": {
                      "id": "7a1e2f30-9c4d-4b5e-8f60-1a2b3c4d5e6f",
                      "name": "Production"
                    },
                    "updated_at": "2026-10-06T15:12:00Z"
                  },
                  "url": "https://api.woodsystems.com/v1/jobs/3f9a1c77-5e3b-4a02-9d8e-2c7b6a1f0e4d"
                },
                "id": "a0b1c2d3-e4f5-4a6b-8c7d-9e0f1a2b3c4d",
                "livemode": true,
                "object": "event",
                "source": {
                  "kind": "ui",
                  "user_id": "e1d2c3b4-a596-4877-8695-a4b3c2d1e0f9"
                },
                "tenant_id": "5c8d2e1f-3a4b-4c6d-8e9f-0a1b2c3d4e5f",
                "type": "job.converted"
              },
              "schema": {
                "$ref": "#/components/schemas/WebhookEvent"
              }
            }
          },
          "required": true
        },
        "responses": {
          "2XX": {
            "description": "Received. Anything else is retried."
          }
        },
        "summary": "An opportunity was won and became a job.",
        "tags": [
          "Webhooks"
        ]
      }
    },
    "job.created": {
      "post": {
        "description": "Verify `WoodSystems-Signature: t=<unix>,v1=<hex>[,v1=<hex>]`: compute HMAC-SHA256 with the endpoint secret over `<t>.<raw body>`, compare in constant time to any `v1`, and reject when `t` is more than 300 seconds old. Treat `WoodSystems-Event-Id` as the idempotency key; retries carry `WoodSystems-Replay: true`. Answer any 2xx within 10 seconds. Failed deliveries are retried after 1m, 5m, 30m, 2h, 12h and 24h, then given up. An endpoint failing 20 times in a row over a day, or answering 410, is switched off and the account admins are told.",
        "operationId": "webhook.job.created",
        "parameters": [
          {
            "description": "t=<unix>,v1=<hex>; see the description.",
            "in": "header",
            "name": "WoodSystems-Signature",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The event type.",
            "in": "header",
            "name": "WoodSystems-Event",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Stable per event; use it to drop repeats.",
            "in": "header",
            "name": "WoodSystems-Event-Id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Stable per delivery to your endpoint.",
            "in": "header",
            "name": "WoodSystems-Delivery-Id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "1 for the first try.",
            "in": "header",
            "name": "WoodSystems-Attempt",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "true on retries.",
            "in": "header",
            "name": "WoodSystems-Replay",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "live or sandbox.",
            "in": "header",
            "name": "WoodSystems-Environment",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The prefix of your key, when the change came from it.",
            "in": "header",
            "name": "WoodSystems-Source-Key",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "api_version": "v1",
                "created_at": "2026-10-06T15:12:00Z",
                "data": {
                  "object": {
                    "id": "3f9a1c77-5e3b-4a02-9d8e-2c7b6a1f0e4d",
                    "name": "Whitfield kitchen remodel",
                    "reference": "J1042",
                    "stage": "job",
                    "status": {
                      "id": "7a1e2f30-9c4d-4b5e-8f60-1a2b3c4d5e6f",
                      "name": "Production"
                    },
                    "updated_at": "2026-10-06T15:12:00Z"
                  },
                  "url": "https://api.woodsystems.com/v1/jobs/3f9a1c77-5e3b-4a02-9d8e-2c7b6a1f0e4d"
                },
                "id": "a0b1c2d3-e4f5-4a6b-8c7d-9e0f1a2b3c4d",
                "livemode": true,
                "object": "event",
                "source": {
                  "kind": "ui",
                  "user_id": "e1d2c3b4-a596-4877-8695-a4b3c2d1e0f9"
                },
                "tenant_id": "5c8d2e1f-3a4b-4c6d-8e9f-0a1b2c3d4e5f",
                "type": "job.created"
              },
              "schema": {
                "$ref": "#/components/schemas/WebhookEvent"
              }
            }
          },
          "required": true
        },
        "responses": {
          "2XX": {
            "description": "Received. Anything else is retried."
          }
        },
        "summary": "A lead, opportunity or job was created, in the app, through the API or from a website form.",
        "tags": [
          "Webhooks"
        ]
      }
    },
    "job.lost": {
      "post": {
        "description": "Verify `WoodSystems-Signature: t=<unix>,v1=<hex>[,v1=<hex>]`: compute HMAC-SHA256 with the endpoint secret over `<t>.<raw body>`, compare in constant time to any `v1`, and reject when `t` is more than 300 seconds old. Treat `WoodSystems-Event-Id` as the idempotency key; retries carry `WoodSystems-Replay: true`. Answer any 2xx within 10 seconds. Failed deliveries are retried after 1m, 5m, 30m, 2h, 12h and 24h, then given up. An endpoint failing 20 times in a row over a day, or answering 410, is switched off and the account admins are told.",
        "operationId": "webhook.job.lost",
        "parameters": [
          {
            "description": "t=<unix>,v1=<hex>; see the description.",
            "in": "header",
            "name": "WoodSystems-Signature",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The event type.",
            "in": "header",
            "name": "WoodSystems-Event",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Stable per event; use it to drop repeats.",
            "in": "header",
            "name": "WoodSystems-Event-Id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Stable per delivery to your endpoint.",
            "in": "header",
            "name": "WoodSystems-Delivery-Id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "1 for the first try.",
            "in": "header",
            "name": "WoodSystems-Attempt",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "true on retries.",
            "in": "header",
            "name": "WoodSystems-Replay",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "live or sandbox.",
            "in": "header",
            "name": "WoodSystems-Environment",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The prefix of your key, when the change came from it.",
            "in": "header",
            "name": "WoodSystems-Source-Key",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "api_version": "v1",
                "created_at": "2026-10-06T15:12:00Z",
                "data": {
                  "object": {
                    "id": "3f9a1c77-5e3b-4a02-9d8e-2c7b6a1f0e4d",
                    "name": "Whitfield kitchen remodel",
                    "reference": "J1042",
                    "stage": "job",
                    "status": {
                      "id": "7a1e2f30-9c4d-4b5e-8f60-1a2b3c4d5e6f",
                      "name": "Production"
                    },
                    "updated_at": "2026-10-06T15:12:00Z"
                  },
                  "url": "https://api.woodsystems.com/v1/jobs/3f9a1c77-5e3b-4a02-9d8e-2c7b6a1f0e4d"
                },
                "id": "a0b1c2d3-e4f5-4a6b-8c7d-9e0f1a2b3c4d",
                "livemode": true,
                "object": "event",
                "source": {
                  "kind": "ui",
                  "user_id": "e1d2c3b4-a596-4877-8695-a4b3c2d1e0f9"
                },
                "tenant_id": "5c8d2e1f-3a4b-4c6d-8e9f-0a1b2c3d4e5f",
                "type": "job.lost"
              },
              "schema": {
                "$ref": "#/components/schemas/WebhookEvent"
              }
            }
          },
          "required": true
        },
        "responses": {
          "2XX": {
            "description": "Received. Anything else is retried."
          }
        },
        "summary": "A lead or opportunity was marked lost.",
        "tags": [
          "Webhooks"
        ]
      }
    },
    "job.status_changed": {
      "post": {
        "description": "Verify `WoodSystems-Signature: t=<unix>,v1=<hex>[,v1=<hex>]`: compute HMAC-SHA256 with the endpoint secret over `<t>.<raw body>`, compare in constant time to any `v1`, and reject when `t` is more than 300 seconds old. Treat `WoodSystems-Event-Id` as the idempotency key; retries carry `WoodSystems-Replay: true`. Answer any 2xx within 10 seconds. Failed deliveries are retried after 1m, 5m, 30m, 2h, 12h and 24h, then given up. An endpoint failing 20 times in a row over a day, or answering 410, is switched off and the account admins are told.",
        "operationId": "webhook.job.status_changed",
        "parameters": [
          {
            "description": "t=<unix>,v1=<hex>; see the description.",
            "in": "header",
            "name": "WoodSystems-Signature",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The event type.",
            "in": "header",
            "name": "WoodSystems-Event",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Stable per event; use it to drop repeats.",
            "in": "header",
            "name": "WoodSystems-Event-Id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Stable per delivery to your endpoint.",
            "in": "header",
            "name": "WoodSystems-Delivery-Id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "1 for the first try.",
            "in": "header",
            "name": "WoodSystems-Attempt",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "true on retries.",
            "in": "header",
            "name": "WoodSystems-Replay",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "live or sandbox.",
            "in": "header",
            "name": "WoodSystems-Environment",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The prefix of your key, when the change came from it.",
            "in": "header",
            "name": "WoodSystems-Source-Key",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "api_version": "v1",
                "created_at": "2026-10-06T15:12:00Z",
                "data": {
                  "object": {
                    "id": "3f9a1c77-5e3b-4a02-9d8e-2c7b6a1f0e4d",
                    "name": "Whitfield kitchen remodel",
                    "reference": "J1042",
                    "stage": "job",
                    "status": {
                      "id": "7a1e2f30-9c4d-4b5e-8f60-1a2b3c4d5e6f",
                      "name": "Production"
                    },
                    "updated_at": "2026-10-06T15:12:00Z"
                  },
                  "previous_attributes": {
                    "status": {
                      "id": "9b8a7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
                      "name": "Backlog"
                    }
                  },
                  "url": "https://api.woodsystems.com/v1/jobs/3f9a1c77-5e3b-4a02-9d8e-2c7b6a1f0e4d"
                },
                "id": "a0b1c2d3-e4f5-4a6b-8c7d-9e0f1a2b3c4d",
                "livemode": true,
                "object": "event",
                "source": {
                  "kind": "ui",
                  "user_id": "e1d2c3b4-a596-4877-8695-a4b3c2d1e0f9"
                },
                "tenant_id": "5c8d2e1f-3a4b-4c6d-8e9f-0a1b2c3d4e5f",
                "type": "job.status_changed"
              },
              "schema": {
                "$ref": "#/components/schemas/WebhookEvent"
              }
            }
          },
          "required": true
        },
        "responses": {
          "2XX": {
            "description": "Received. Anything else is retried."
          }
        },
        "summary": "A job moved to another main status or phase.",
        "tags": [
          "Webhooks"
        ]
      }
    },
    "message.created": {
      "post": {
        "description": "Verify `WoodSystems-Signature: t=<unix>,v1=<hex>[,v1=<hex>]`: compute HMAC-SHA256 with the endpoint secret over `<t>.<raw body>`, compare in constant time to any `v1`, and reject when `t` is more than 300 seconds old. Treat `WoodSystems-Event-Id` as the idempotency key; retries carry `WoodSystems-Replay: true`. Answer any 2xx within 10 seconds. Failed deliveries are retried after 1m, 5m, 30m, 2h, 12h and 24h, then given up. An endpoint failing 20 times in a row over a day, or answering 410, is switched off and the account admins are told.",
        "operationId": "webhook.message.created",
        "parameters": [
          {
            "description": "t=<unix>,v1=<hex>; see the description.",
            "in": "header",
            "name": "WoodSystems-Signature",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The event type.",
            "in": "header",
            "name": "WoodSystems-Event",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Stable per event; use it to drop repeats.",
            "in": "header",
            "name": "WoodSystems-Event-Id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Stable per delivery to your endpoint.",
            "in": "header",
            "name": "WoodSystems-Delivery-Id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "1 for the first try.",
            "in": "header",
            "name": "WoodSystems-Attempt",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "true on retries.",
            "in": "header",
            "name": "WoodSystems-Replay",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "live or sandbox.",
            "in": "header",
            "name": "WoodSystems-Environment",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The prefix of your key, when the change came from it.",
            "in": "header",
            "name": "WoodSystems-Source-Key",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "api_version": "v1",
                "created_at": "2026-10-06T15:12:00Z",
                "data": {
                  "object": {
                    "author_id": "e1d2c3b4-a596-4877-8695-a4b3c2d1e0f9",
                    "content": "Hardware arrived, starting Monday.",
                    "id": "4f5a6b7c-8d9e-4f0a-9b1c-2d3e4f5a6b7c",
                    "job_id": "3f9a1c77-5e3b-4a02-9d8e-2c7b6a1f0e4d"
                  }
                },
                "id": "a0b1c2d3-e4f5-4a6b-8c7d-9e0f1a2b3c4d",
                "livemode": true,
                "object": "event",
                "source": {
                  "kind": "ui",
                  "user_id": "e1d2c3b4-a596-4877-8695-a4b3c2d1e0f9"
                },
                "tenant_id": "5c8d2e1f-3a4b-4c6d-8e9f-0a1b2c3d4e5f",
                "type": "message.created"
              },
              "schema": {
                "$ref": "#/components/schemas/WebhookEvent"
              }
            }
          },
          "required": true
        },
        "responses": {
          "2XX": {
            "description": "Received. Anything else is retried."
          }
        },
        "summary": "Someone posted a note on a job's message thread.",
        "tags": [
          "Webhooks"
        ]
      }
    },
    "payment.received": {
      "post": {
        "description": "Verify `WoodSystems-Signature: t=<unix>,v1=<hex>[,v1=<hex>]`: compute HMAC-SHA256 with the endpoint secret over `<t>.<raw body>`, compare in constant time to any `v1`, and reject when `t` is more than 300 seconds old. Treat `WoodSystems-Event-Id` as the idempotency key; retries carry `WoodSystems-Replay: true`. Answer any 2xx within 10 seconds. Failed deliveries are retried after 1m, 5m, 30m, 2h, 12h and 24h, then given up. An endpoint failing 20 times in a row over a day, or answering 410, is switched off and the account admins are told.",
        "operationId": "webhook.payment.received",
        "parameters": [
          {
            "description": "t=<unix>,v1=<hex>; see the description.",
            "in": "header",
            "name": "WoodSystems-Signature",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The event type.",
            "in": "header",
            "name": "WoodSystems-Event",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Stable per event; use it to drop repeats.",
            "in": "header",
            "name": "WoodSystems-Event-Id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Stable per delivery to your endpoint.",
            "in": "header",
            "name": "WoodSystems-Delivery-Id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "1 for the first try.",
            "in": "header",
            "name": "WoodSystems-Attempt",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "true on retries.",
            "in": "header",
            "name": "WoodSystems-Replay",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "live or sandbox.",
            "in": "header",
            "name": "WoodSystems-Environment",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The prefix of your key, when the change came from it.",
            "in": "header",
            "name": "WoodSystems-Source-Key",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "api_version": "v1",
                "created_at": "2026-10-06T15:12:00Z",
                "data": {
                  "object": {
                    "id": "4b5c6d7e-8f9a-4b0c-9d1e-2f3a4b5c6d7e",
                    "invoice_id": "2f3a4b5c-6d7e-4f8a-9b0c-1d2e3f4a5b6c",
                    "job_id": "3f9a1c77-5e3b-4a02-9d8e-2c7b6a1f0e4d",
                    "received_at": "2026-10-06T15:12:00Z",
                    "status": {
                      "id": "5c6d7e8f-9a0b-4c1d-8e2f-3a4b5c6d7e8f",
                      "name": "Received"
                    }
                  },
                  "url": "https://api.woodsystems.com/v1/payments/4b5c6d7e-8f9a-4b0c-9d1e-2f3a4b5c6d7e"
                },
                "id": "a0b1c2d3-e4f5-4a6b-8c7d-9e0f1a2b3c4d",
                "livemode": true,
                "object": "event",
                "source": {
                  "kind": "ui",
                  "user_id": "e1d2c3b4-a596-4877-8695-a4b3c2d1e0f9"
                },
                "tenant_id": "5c8d2e1f-3a4b-4c6d-8e9f-0a1b2c3d4e5f",
                "type": "payment.received"
              },
              "schema": {
                "$ref": "#/components/schemas/WebhookEvent"
              }
            }
          },
          "required": true
        },
        "responses": {
          "2XX": {
            "description": "Received. Anything else is retried."
          }
        },
        "summary": "A payment was received.",
        "tags": [
          "Webhooks"
        ]
      }
    },
    "ping": {
      "post": {
        "description": "Verify `WoodSystems-Signature: t=<unix>,v1=<hex>[,v1=<hex>]`: compute HMAC-SHA256 with the endpoint secret over `<t>.<raw body>`, compare in constant time to any `v1`, and reject when `t` is more than 300 seconds old. Treat `WoodSystems-Event-Id` as the idempotency key; retries carry `WoodSystems-Replay: true`. Answer any 2xx within 10 seconds. Failed deliveries are retried after 1m, 5m, 30m, 2h, 12h and 24h, then given up. An endpoint failing 20 times in a row over a day, or answering 410, is switched off and the account admins are told.",
        "operationId": "webhook.ping",
        "parameters": [
          {
            "description": "t=<unix>,v1=<hex>; see the description.",
            "in": "header",
            "name": "WoodSystems-Signature",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The event type.",
            "in": "header",
            "name": "WoodSystems-Event",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Stable per event; use it to drop repeats.",
            "in": "header",
            "name": "WoodSystems-Event-Id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Stable per delivery to your endpoint.",
            "in": "header",
            "name": "WoodSystems-Delivery-Id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "1 for the first try.",
            "in": "header",
            "name": "WoodSystems-Attempt",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "true on retries.",
            "in": "header",
            "name": "WoodSystems-Replay",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "live or sandbox.",
            "in": "header",
            "name": "WoodSystems-Environment",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The prefix of your key, when the change came from it.",
            "in": "header",
            "name": "WoodSystems-Source-Key",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "api_version": "v1",
                "created_at": "2026-10-06T15:12:00Z",
                "data": {
                  "object": {
                    "endpoint_id": "6d1f0a2b-3c4d-4e5f-8a9b-0c1d2e3f4a5b"
                  }
                },
                "id": "a0b1c2d3-e4f5-4a6b-8c7d-9e0f1a2b3c4d",
                "livemode": true,
                "object": "event",
                "source": {
                  "kind": "ui",
                  "user_id": "e1d2c3b4-a596-4877-8695-a4b3c2d1e0f9"
                },
                "tenant_id": "5c8d2e1f-3a4b-4c6d-8e9f-0a1b2c3d4e5f",
                "type": "ping"
              },
              "schema": {
                "$ref": "#/components/schemas/WebhookEvent"
              }
            }
          },
          "required": true
        },
        "responses": {
          "2XX": {
            "description": "Received. Anything else is retried."
          }
        },
        "summary": "Sent when you press Send test, to check an endpoint.",
        "tags": [
          "Webhooks"
        ]
      }
    },
    "purchase_order.created": {
      "post": {
        "description": "Verify `WoodSystems-Signature: t=<unix>,v1=<hex>[,v1=<hex>]`: compute HMAC-SHA256 with the endpoint secret over `<t>.<raw body>`, compare in constant time to any `v1`, and reject when `t` is more than 300 seconds old. Treat `WoodSystems-Event-Id` as the idempotency key; retries carry `WoodSystems-Replay: true`. Answer any 2xx within 10 seconds. Failed deliveries are retried after 1m, 5m, 30m, 2h, 12h and 24h, then given up. An endpoint failing 20 times in a row over a day, or answering 410, is switched off and the account admins are told.",
        "operationId": "webhook.purchase_order.created",
        "parameters": [
          {
            "description": "t=<unix>,v1=<hex>; see the description.",
            "in": "header",
            "name": "WoodSystems-Signature",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The event type.",
            "in": "header",
            "name": "WoodSystems-Event",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Stable per event; use it to drop repeats.",
            "in": "header",
            "name": "WoodSystems-Event-Id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Stable per delivery to your endpoint.",
            "in": "header",
            "name": "WoodSystems-Delivery-Id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "1 for the first try.",
            "in": "header",
            "name": "WoodSystems-Attempt",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "true on retries.",
            "in": "header",
            "name": "WoodSystems-Replay",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "live or sandbox.",
            "in": "header",
            "name": "WoodSystems-Environment",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The prefix of your key, when the change came from it.",
            "in": "header",
            "name": "WoodSystems-Source-Key",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "api_version": "v1",
                "created_at": "2026-10-06T15:12:00Z",
                "data": {
                  "object": {
                    "id": "1c2d3e4f-5a6b-4c7d-8e8f-9a0b1c2d3e4f",
                    "job_id": "3f9a1c77-5e3b-4a02-9d8e-2c7b6a1f0e4d",
                    "name": "Plywood",
                    "reference": "PO118",
                    "status": "submitted",
                    "updated_at": "2026-10-06T15:12:00Z",
                    "vendor_id": "2d3e4f5a-6b7c-4d8e-9f0a-1b2c3d4e5f6a"
                  },
                  "url": "https://api.woodsystems.com/v1/purchase-orders/1c2d3e4f-5a6b-4c7d-8e8f-9a0b1c2d3e4f"
                },
                "id": "a0b1c2d3-e4f5-4a6b-8c7d-9e0f1a2b3c4d",
                "livemode": true,
                "object": "event",
                "source": {
                  "kind": "ui",
                  "user_id": "e1d2c3b4-a596-4877-8695-a4b3c2d1e0f9"
                },
                "tenant_id": "5c8d2e1f-3a4b-4c6d-8e9f-0a1b2c3d4e5f",
                "type": "purchase_order.created"
              },
              "schema": {
                "$ref": "#/components/schemas/WebhookEvent"
              }
            }
          },
          "required": true
        },
        "responses": {
          "2XX": {
            "description": "Received. Anything else is retried."
          }
        },
        "summary": "A purchase order was created.",
        "tags": [
          "Webhooks"
        ]
      }
    },
    "purchase_order.status_changed": {
      "post": {
        "description": "Verify `WoodSystems-Signature: t=<unix>,v1=<hex>[,v1=<hex>]`: compute HMAC-SHA256 with the endpoint secret over `<t>.<raw body>`, compare in constant time to any `v1`, and reject when `t` is more than 300 seconds old. Treat `WoodSystems-Event-Id` as the idempotency key; retries carry `WoodSystems-Replay: true`. Answer any 2xx within 10 seconds. Failed deliveries are retried after 1m, 5m, 30m, 2h, 12h and 24h, then given up. An endpoint failing 20 times in a row over a day, or answering 410, is switched off and the account admins are told.",
        "operationId": "webhook.purchase_order.status_changed",
        "parameters": [
          {
            "description": "t=<unix>,v1=<hex>; see the description.",
            "in": "header",
            "name": "WoodSystems-Signature",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The event type.",
            "in": "header",
            "name": "WoodSystems-Event",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Stable per event; use it to drop repeats.",
            "in": "header",
            "name": "WoodSystems-Event-Id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Stable per delivery to your endpoint.",
            "in": "header",
            "name": "WoodSystems-Delivery-Id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "1 for the first try.",
            "in": "header",
            "name": "WoodSystems-Attempt",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "true on retries.",
            "in": "header",
            "name": "WoodSystems-Replay",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "live or sandbox.",
            "in": "header",
            "name": "WoodSystems-Environment",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The prefix of your key, when the change came from it.",
            "in": "header",
            "name": "WoodSystems-Source-Key",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "api_version": "v1",
                "created_at": "2026-10-06T15:12:00Z",
                "data": {
                  "object": {
                    "id": "1c2d3e4f-5a6b-4c7d-8e8f-9a0b1c2d3e4f",
                    "job_id": "3f9a1c77-5e3b-4a02-9d8e-2c7b6a1f0e4d",
                    "name": "Plywood",
                    "reference": "PO118",
                    "status": "submitted",
                    "updated_at": "2026-10-06T15:12:00Z",
                    "vendor_id": "2d3e4f5a-6b7c-4d8e-9f0a-1b2c3d4e5f6a"
                  },
                  "previous_attributes": {
                    "status": {
                      "id": "9b8a7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
                      "name": "Backlog"
                    }
                  },
                  "url": "https://api.woodsystems.com/v1/purchase-orders/1c2d3e4f-5a6b-4c7d-8e8f-9a0b1c2d3e4f"
                },
                "id": "a0b1c2d3-e4f5-4a6b-8c7d-9e0f1a2b3c4d",
                "livemode": true,
                "object": "event",
                "source": {
                  "kind": "ui",
                  "user_id": "e1d2c3b4-a596-4877-8695-a4b3c2d1e0f9"
                },
                "tenant_id": "5c8d2e1f-3a4b-4c6d-8e9f-0a1b2c3d4e5f",
                "type": "purchase_order.status_changed"
              },
              "schema": {
                "$ref": "#/components/schemas/WebhookEvent"
              }
            }
          },
          "required": true
        },
        "responses": {
          "2XX": {
            "description": "Received. Anything else is retried."
          }
        },
        "summary": "A purchase order moved to another status.",
        "tags": [
          "Webhooks"
        ]
      }
    },
    "task.completed": {
      "post": {
        "description": "Verify `WoodSystems-Signature: t=<unix>,v1=<hex>[,v1=<hex>]`: compute HMAC-SHA256 with the endpoint secret over `<t>.<raw body>`, compare in constant time to any `v1`, and reject when `t` is more than 300 seconds old. Treat `WoodSystems-Event-Id` as the idempotency key; retries carry `WoodSystems-Replay: true`. Answer any 2xx within 10 seconds. Failed deliveries are retried after 1m, 5m, 30m, 2h, 12h and 24h, then given up. An endpoint failing 20 times in a row over a day, or answering 410, is switched off and the account admins are told.",
        "operationId": "webhook.task.completed",
        "parameters": [
          {
            "description": "t=<unix>,v1=<hex>; see the description.",
            "in": "header",
            "name": "WoodSystems-Signature",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The event type.",
            "in": "header",
            "name": "WoodSystems-Event",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Stable per event; use it to drop repeats.",
            "in": "header",
            "name": "WoodSystems-Event-Id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Stable per delivery to your endpoint.",
            "in": "header",
            "name": "WoodSystems-Delivery-Id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "1 for the first try.",
            "in": "header",
            "name": "WoodSystems-Attempt",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "true on retries.",
            "in": "header",
            "name": "WoodSystems-Replay",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "live or sandbox.",
            "in": "header",
            "name": "WoodSystems-Environment",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The prefix of your key, when the change came from it.",
            "in": "header",
            "name": "WoodSystems-Source-Key",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "api_version": "v1",
                "created_at": "2026-10-06T15:12:00Z",
                "data": {
                  "object": {
                    "assignee_ids": [
                      "e1d2c3b4-a596-4877-8695-a4b3c2d1e0f9"
                    ],
                    "due_date": "2026-10-10",
                    "id": "6d7e8f9a-0b1c-4d2e-9f3a-4b5c6d7e8f9a",
                    "job_id": "3f9a1c77-5e3b-4a02-9d8e-2c7b6a1f0e4d",
                    "status": {
                      "id": "7e8f9a0b-1c2d-4e3f-8a4b-5c6d7e8f9a0b",
                      "name": "Complete"
                    },
                    "title": "Order hardware",
                    "updated_at": "2026-10-06T15:12:00Z"
                  },
                  "url": "https://api.woodsystems.com/v1/tasks/6d7e8f9a-0b1c-4d2e-9f3a-4b5c6d7e8f9a"
                },
                "id": "a0b1c2d3-e4f5-4a6b-8c7d-9e0f1a2b3c4d",
                "livemode": true,
                "object": "event",
                "source": {
                  "kind": "ui",
                  "user_id": "e1d2c3b4-a596-4877-8695-a4b3c2d1e0f9"
                },
                "tenant_id": "5c8d2e1f-3a4b-4c6d-8e9f-0a1b2c3d4e5f",
                "type": "task.completed"
              },
              "schema": {
                "$ref": "#/components/schemas/WebhookEvent"
              }
            }
          },
          "required": true
        },
        "responses": {
          "2XX": {
            "description": "Received. Anything else is retried."
          }
        },
        "summary": "A task was marked complete.",
        "tags": [
          "Webhooks"
        ]
      }
    },
    "task.created": {
      "post": {
        "description": "Verify `WoodSystems-Signature: t=<unix>,v1=<hex>[,v1=<hex>]`: compute HMAC-SHA256 with the endpoint secret over `<t>.<raw body>`, compare in constant time to any `v1`, and reject when `t` is more than 300 seconds old. Treat `WoodSystems-Event-Id` as the idempotency key; retries carry `WoodSystems-Replay: true`. Answer any 2xx within 10 seconds. Failed deliveries are retried after 1m, 5m, 30m, 2h, 12h and 24h, then given up. An endpoint failing 20 times in a row over a day, or answering 410, is switched off and the account admins are told.",
        "operationId": "webhook.task.created",
        "parameters": [
          {
            "description": "t=<unix>,v1=<hex>; see the description.",
            "in": "header",
            "name": "WoodSystems-Signature",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The event type.",
            "in": "header",
            "name": "WoodSystems-Event",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Stable per event; use it to drop repeats.",
            "in": "header",
            "name": "WoodSystems-Event-Id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Stable per delivery to your endpoint.",
            "in": "header",
            "name": "WoodSystems-Delivery-Id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "1 for the first try.",
            "in": "header",
            "name": "WoodSystems-Attempt",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "true on retries.",
            "in": "header",
            "name": "WoodSystems-Replay",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "live or sandbox.",
            "in": "header",
            "name": "WoodSystems-Environment",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The prefix of your key, when the change came from it.",
            "in": "header",
            "name": "WoodSystems-Source-Key",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "api_version": "v1",
                "created_at": "2026-10-06T15:12:00Z",
                "data": {
                  "object": {
                    "assignee_ids": [
                      "e1d2c3b4-a596-4877-8695-a4b3c2d1e0f9"
                    ],
                    "due_date": "2026-10-10",
                    "id": "6d7e8f9a-0b1c-4d2e-9f3a-4b5c6d7e8f9a",
                    "job_id": "3f9a1c77-5e3b-4a02-9d8e-2c7b6a1f0e4d",
                    "status": {
                      "id": "7e8f9a0b-1c2d-4e3f-8a4b-5c6d7e8f9a0b",
                      "name": "Complete"
                    },
                    "title": "Order hardware",
                    "updated_at": "2026-10-06T15:12:00Z"
                  },
                  "url": "https://api.woodsystems.com/v1/tasks/6d7e8f9a-0b1c-4d2e-9f3a-4b5c6d7e8f9a"
                },
                "id": "a0b1c2d3-e4f5-4a6b-8c7d-9e0f1a2b3c4d",
                "livemode": true,
                "object": "event",
                "source": {
                  "kind": "ui",
                  "user_id": "e1d2c3b4-a596-4877-8695-a4b3c2d1e0f9"
                },
                "tenant_id": "5c8d2e1f-3a4b-4c6d-8e9f-0a1b2c3d4e5f",
                "type": "task.created"
              },
              "schema": {
                "$ref": "#/components/schemas/WebhookEvent"
              }
            }
          },
          "required": true
        },
        "responses": {
          "2XX": {
            "description": "Received. Anything else is retried."
          }
        },
        "summary": "A task was created.",
        "tags": [
          "Webhooks"
        ]
      }
    },
    "timeline.date_confirmed": {
      "post": {
        "description": "Verify `WoodSystems-Signature: t=<unix>,v1=<hex>[,v1=<hex>]`: compute HMAC-SHA256 with the endpoint secret over `<t>.<raw body>`, compare in constant time to any `v1`, and reject when `t` is more than 300 seconds old. Treat `WoodSystems-Event-Id` as the idempotency key; retries carry `WoodSystems-Replay: true`. Answer any 2xx within 10 seconds. Failed deliveries are retried after 1m, 5m, 30m, 2h, 12h and 24h, then given up. An endpoint failing 20 times in a row over a day, or answering 410, is switched off and the account admins are told.",
        "operationId": "webhook.timeline.date_confirmed",
        "parameters": [
          {
            "description": "t=<unix>,v1=<hex>; see the description.",
            "in": "header",
            "name": "WoodSystems-Signature",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The event type.",
            "in": "header",
            "name": "WoodSystems-Event",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Stable per event; use it to drop repeats.",
            "in": "header",
            "name": "WoodSystems-Event-Id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Stable per delivery to your endpoint.",
            "in": "header",
            "name": "WoodSystems-Delivery-Id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "1 for the first try.",
            "in": "header",
            "name": "WoodSystems-Attempt",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "true on retries.",
            "in": "header",
            "name": "WoodSystems-Replay",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "live or sandbox.",
            "in": "header",
            "name": "WoodSystems-Environment",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The prefix of your key, when the change came from it.",
            "in": "header",
            "name": "WoodSystems-Source-Key",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "api_version": "v1",
                "created_at": "2026-10-06T15:12:00Z",
                "data": {
                  "object": {
                    "date": "2026-11-16",
                    "definition_id": "5a6b7c8d-9e0f-4a1b-8c2d-3e4f5a6b7c8d",
                    "job_id": "3f9a1c77-5e3b-4a02-9d8e-2c7b6a1f0e4d",
                    "key": "install_start",
                    "label": "Install start"
                  }
                },
                "id": "a0b1c2d3-e4f5-4a6b-8c7d-9e0f1a2b3c4d",
                "livemode": true,
                "object": "event",
                "source": {
                  "kind": "ui",
                  "user_id": "e1d2c3b4-a596-4877-8695-a4b3c2d1e0f9"
                },
                "tenant_id": "5c8d2e1f-3a4b-4c6d-8e9f-0a1b2c3d4e5f",
                "type": "timeline.date_confirmed"
              },
              "schema": {
                "$ref": "#/components/schemas/WebhookEvent"
              }
            }
          },
          "required": true
        },
        "responses": {
          "2XX": {
            "description": "Received. Anything else is retried."
          }
        },
        "summary": "A job date was confirmed.",
        "tags": [
          "Webhooks"
        ]
      }
    },
    "work_order.completed": {
      "post": {
        "description": "Verify `WoodSystems-Signature: t=<unix>,v1=<hex>[,v1=<hex>]`: compute HMAC-SHA256 with the endpoint secret over `<t>.<raw body>`, compare in constant time to any `v1`, and reject when `t` is more than 300 seconds old. Treat `WoodSystems-Event-Id` as the idempotency key; retries carry `WoodSystems-Replay: true`. Answer any 2xx within 10 seconds. Failed deliveries are retried after 1m, 5m, 30m, 2h, 12h and 24h, then given up. An endpoint failing 20 times in a row over a day, or answering 410, is switched off and the account admins are told.",
        "operationId": "webhook.work_order.completed",
        "parameters": [
          {
            "description": "t=<unix>,v1=<hex>; see the description.",
            "in": "header",
            "name": "WoodSystems-Signature",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The event type.",
            "in": "header",
            "name": "WoodSystems-Event",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Stable per event; use it to drop repeats.",
            "in": "header",
            "name": "WoodSystems-Event-Id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Stable per delivery to your endpoint.",
            "in": "header",
            "name": "WoodSystems-Delivery-Id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "1 for the first try.",
            "in": "header",
            "name": "WoodSystems-Attempt",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "true on retries.",
            "in": "header",
            "name": "WoodSystems-Replay",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "live or sandbox.",
            "in": "header",
            "name": "WoodSystems-Environment",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The prefix of your key, when the change came from it.",
            "in": "header",
            "name": "WoodSystems-Source-Key",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "api_version": "v1",
                "created_at": "2026-10-06T15:12:00Z",
                "data": {
                  "object": {
                    "id": "9a0b1c2d-3e4f-4a5b-8c6d-7e8f9a0b1c2d",
                    "job_id": "3f9a1c77-5e3b-4a02-9d8e-2c7b6a1f0e4d",
                    "name": "Kitchen boxes",
                    "status": {
                      "id": "0b1c2d3e-4f5a-4b6c-9d7e-8f9a0b1c2d3e",
                      "name": "Cutting"
                    },
                    "type": {
                      "id": "3c9d1e2f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
                      "name": "Production"
                    },
                    "updated_at": "2026-10-06T15:12:00Z"
                  },
                  "url": "https://api.woodsystems.com/v1/work-orders/9a0b1c2d-3e4f-4a5b-8c6d-7e8f9a0b1c2d"
                },
                "id": "a0b1c2d3-e4f5-4a6b-8c7d-9e0f1a2b3c4d",
                "livemode": true,
                "object": "event",
                "source": {
                  "kind": "ui",
                  "user_id": "e1d2c3b4-a596-4877-8695-a4b3c2d1e0f9"
                },
                "tenant_id": "5c8d2e1f-3a4b-4c6d-8e9f-0a1b2c3d4e5f",
                "type": "work_order.completed"
              },
              "schema": {
                "$ref": "#/components/schemas/WebhookEvent"
              }
            }
          },
          "required": true
        },
        "responses": {
          "2XX": {
            "description": "Received. Anything else is retried."
          }
        },
        "summary": "A work order reached a complete status.",
        "tags": [
          "Webhooks"
        ]
      }
    },
    "work_order.created": {
      "post": {
        "description": "Verify `WoodSystems-Signature: t=<unix>,v1=<hex>[,v1=<hex>]`: compute HMAC-SHA256 with the endpoint secret over `<t>.<raw body>`, compare in constant time to any `v1`, and reject when `t` is more than 300 seconds old. Treat `WoodSystems-Event-Id` as the idempotency key; retries carry `WoodSystems-Replay: true`. Answer any 2xx within 10 seconds. Failed deliveries are retried after 1m, 5m, 30m, 2h, 12h and 24h, then given up. An endpoint failing 20 times in a row over a day, or answering 410, is switched off and the account admins are told.",
        "operationId": "webhook.work_order.created",
        "parameters": [
          {
            "description": "t=<unix>,v1=<hex>; see the description.",
            "in": "header",
            "name": "WoodSystems-Signature",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The event type.",
            "in": "header",
            "name": "WoodSystems-Event",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Stable per event; use it to drop repeats.",
            "in": "header",
            "name": "WoodSystems-Event-Id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Stable per delivery to your endpoint.",
            "in": "header",
            "name": "WoodSystems-Delivery-Id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "1 for the first try.",
            "in": "header",
            "name": "WoodSystems-Attempt",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "true on retries.",
            "in": "header",
            "name": "WoodSystems-Replay",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "live or sandbox.",
            "in": "header",
            "name": "WoodSystems-Environment",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The prefix of your key, when the change came from it.",
            "in": "header",
            "name": "WoodSystems-Source-Key",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "api_version": "v1",
                "created_at": "2026-10-06T15:12:00Z",
                "data": {
                  "object": {
                    "id": "9a0b1c2d-3e4f-4a5b-8c6d-7e8f9a0b1c2d",
                    "job_id": "3f9a1c77-5e3b-4a02-9d8e-2c7b6a1f0e4d",
                    "name": "Kitchen boxes",
                    "status": {
                      "id": "0b1c2d3e-4f5a-4b6c-9d7e-8f9a0b1c2d3e",
                      "name": "Cutting"
                    },
                    "type": {
                      "id": "3c9d1e2f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
                      "name": "Production"
                    },
                    "updated_at": "2026-10-06T15:12:00Z"
                  },
                  "url": "https://api.woodsystems.com/v1/work-orders/9a0b1c2d-3e4f-4a5b-8c6d-7e8f9a0b1c2d"
                },
                "id": "a0b1c2d3-e4f5-4a6b-8c7d-9e0f1a2b3c4d",
                "livemode": true,
                "object": "event",
                "source": {
                  "kind": "ui",
                  "user_id": "e1d2c3b4-a596-4877-8695-a4b3c2d1e0f9"
                },
                "tenant_id": "5c8d2e1f-3a4b-4c6d-8e9f-0a1b2c3d4e5f",
                "type": "work_order.created"
              },
              "schema": {
                "$ref": "#/components/schemas/WebhookEvent"
              }
            }
          },
          "required": true
        },
        "responses": {
          "2XX": {
            "description": "Received. Anything else is retried."
          }
        },
        "summary": "A work order was created.",
        "tags": [
          "Webhooks"
        ]
      }
    },
    "work_order.status_changed": {
      "post": {
        "description": "Verify `WoodSystems-Signature: t=<unix>,v1=<hex>[,v1=<hex>]`: compute HMAC-SHA256 with the endpoint secret over `<t>.<raw body>`, compare in constant time to any `v1`, and reject when `t` is more than 300 seconds old. Treat `WoodSystems-Event-Id` as the idempotency key; retries carry `WoodSystems-Replay: true`. Answer any 2xx within 10 seconds. Failed deliveries are retried after 1m, 5m, 30m, 2h, 12h and 24h, then given up. An endpoint failing 20 times in a row over a day, or answering 410, is switched off and the account admins are told.",
        "operationId": "webhook.work_order.status_changed",
        "parameters": [
          {
            "description": "t=<unix>,v1=<hex>; see the description.",
            "in": "header",
            "name": "WoodSystems-Signature",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The event type.",
            "in": "header",
            "name": "WoodSystems-Event",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Stable per event; use it to drop repeats.",
            "in": "header",
            "name": "WoodSystems-Event-Id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Stable per delivery to your endpoint.",
            "in": "header",
            "name": "WoodSystems-Delivery-Id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "1 for the first try.",
            "in": "header",
            "name": "WoodSystems-Attempt",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "true on retries.",
            "in": "header",
            "name": "WoodSystems-Replay",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "live or sandbox.",
            "in": "header",
            "name": "WoodSystems-Environment",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The prefix of your key, when the change came from it.",
            "in": "header",
            "name": "WoodSystems-Source-Key",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "api_version": "v1",
                "created_at": "2026-10-06T15:12:00Z",
                "data": {
                  "object": {
                    "id": "9a0b1c2d-3e4f-4a5b-8c6d-7e8f9a0b1c2d",
                    "job_id": "3f9a1c77-5e3b-4a02-9d8e-2c7b6a1f0e4d",
                    "name": "Kitchen boxes",
                    "status": {
                      "id": "0b1c2d3e-4f5a-4b6c-9d7e-8f9a0b1c2d3e",
                      "name": "Cutting"
                    },
                    "type": {
                      "id": "3c9d1e2f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
                      "name": "Production"
                    },
                    "updated_at": "2026-10-06T15:12:00Z"
                  },
                  "previous_attributes": {
                    "status": {
                      "id": "9b8a7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
                      "name": "Backlog"
                    }
                  },
                  "url": "https://api.woodsystems.com/v1/work-orders/9a0b1c2d-3e4f-4a5b-8c6d-7e8f9a0b1c2d"
                },
                "id": "a0b1c2d3-e4f5-4a6b-8c7d-9e0f1a2b3c4d",
                "livemode": true,
                "object": "event",
                "source": {
                  "kind": "ui",
                  "user_id": "e1d2c3b4-a596-4877-8695-a4b3c2d1e0f9"
                },
                "tenant_id": "5c8d2e1f-3a4b-4c6d-8e9f-0a1b2c3d4e5f",
                "type": "work_order.status_changed"
              },
              "schema": {
                "$ref": "#/components/schemas/WebhookEvent"
              }
            }
          },
          "required": true
        },
        "responses": {
          "2XX": {
            "description": "Received. Anything else is retried."
          }
        },
        "summary": "A work order moved to another status.",
        "tags": [
          "Webhooks"
        ]
      }
    }
  }
}
