{
  "openapi": "3.1.1",
  "info": {
    "title": "SMG Tools API",
    "description": "A business's clients, jobs, leads, appointments and invoices, for the programs it gives a key. Send the key as Authorization: Bearer smgk_…. Every error is application/problem+json with a stable code; every list pages with page and pageSize (up to 100) and takes updatedSince; every create takes an Idempotency-Key.",
    "version": "v1"
  },
  "paths": {
    "/v1/me": {
      "get": {
        "tags": [
          "Me"
        ],
        "summary": "Which business and which key is calling, and what the key may do",
        "operationId": "Me",
        "responses": {
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Me"
                }
              }
            }
          }
        }
      }
    },
    "/v1/clients": {
      "get": {
        "tags": [
          "Clients"
        ],
        "summary": "The business's clients, a page at a time, oldest first",
        "description": "Archived clients are left out unless includeArchived is true. updatedSince returns only the clients created or changed at or after that instant — what a sync asks for. Needs the clients:read scope.",
        "operationId": "ListClients",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          },
          {
            "name": "pageSize",
            "in": "query",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          },
          {
            "name": "updatedSince",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "includeArchived",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PageOfClient"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Clients"
        ],
        "summary": "Add a client",
        "description": "The client's source is Integration, labelled with the key's name, and its history says the key added it. Send an Idempotency-Key to make a retry safe. Needs the clients:write scope.",
        "operationId": "CreateClient",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/NewClient"
              }
            }
          },
          "required": true
        },
        "responses": {
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Client"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "422": {
            "description": "Unprocessable Entity",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/v1/clients/{id}": {
      "get": {
        "tags": [
          "Clients"
        ],
        "summary": "One client",
        "description": "Needs the clients:read scope.",
        "operationId": "GetClient",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Client"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Clients"
        ],
        "summary": "Change a client's details",
        "description": "A field left out is left as it is. An archived client cannot be changed. Needs the clients:write scope.",
        "operationId": "UpdateClient",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ClientChanges"
              }
            }
          },
          "required": true
        },
        "responses": {
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Client"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "422": {
            "description": "Unprocessable Entity",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/v1/jobs": {
      "get": {
        "tags": [
          "Jobs"
        ],
        "summary": "The business's jobs, a page at a time, oldest first",
        "description": "Narrow by status and clientId. Archived jobs are left out unless includeArchived is true. updatedSince returns only the jobs created or changed at or after that instant. Needs the jobs:read scope.",
        "operationId": "ListJobs",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          },
          {
            "name": "pageSize",
            "in": "query",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          },
          {
            "name": "updatedSince",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "clientId",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "includeArchived",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PageOfJob"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Jobs"
        ],
        "summary": "Create a job for one of the business's clients",
        "description": "The job's history says the key created it, and it goes on the business's board, calendar and webhooks exactly as one created in the console. Send an Idempotency-Key to make a retry safe. Needs the jobs:write scope.",
        "operationId": "CreateJob",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/NewJob"
              }
            }
          },
          "required": true
        },
        "responses": {
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Job"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "422": {
            "description": "Unprocessable Entity",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/v1/jobs/{id}": {
      "get": {
        "tags": [
          "Jobs"
        ],
        "summary": "One job",
        "description": "Needs the jobs:read scope.",
        "operationId": "GetJob",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Job"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Jobs"
        ],
        "summary": "Change a job's details",
        "description": "A field left out is left as it is; an empty string clears a text field. The status changes on its own route. Needs the jobs:write scope.",
        "operationId": "UpdateJob",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/JobChanges"
              }
            }
          },
          "required": true
        },
        "responses": {
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Job"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "422": {
            "description": "Unprocessable Entity",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/v1/jobs/{id}/status": {
      "post": {
        "tags": [
          "Jobs"
        ],
        "summary": "Move a job to another status, as the office does",
        "description": "The same checks as the console's: a job with a required checklist step unanswered cannot be Completed without a checklistOverrideReason (checklist_outstanding), and EnRoute and OnSite are the crew's to report. Needs the jobs:write scope.",
        "operationId": "ChangeJobStatus",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/JobStatusChange"
              }
            }
          },
          "required": true
        },
        "responses": {
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Job"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "422": {
            "description": "Unprocessable Entity",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/v1/leads": {
      "get": {
        "tags": [
          "Leads"
        ],
        "summary": "The business's leads, a page at a time, oldest first",
        "description": "Narrow by status. Archived leads are left out unless includeArchived is true or the status asked for is Archived. updatedSince returns only the leads created, contacted, converted or archived at or after that instant. Needs the leads:read scope.",
        "operationId": "ListLeads",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          },
          {
            "name": "pageSize",
            "in": "query",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          },
          {
            "name": "updatedSince",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "includeArchived",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PageOfLead"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Leads"
        ],
        "summary": "Add a lead",
        "description": "Through the same door as the business's public form and its inbound lead address: the same rules, every problem named at once. Its source is Integration, labelled with the key's name. Send an Idempotency-Key to make a retry safe. Needs the leads:write scope.",
        "operationId": "CreateLead",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/NewLead"
              }
            }
          },
          "required": true
        },
        "responses": {
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Lead"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "422": {
            "description": "Unprocessable Entity",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/v1/leads/{id}": {
      "get": {
        "tags": [
          "Leads"
        ],
        "summary": "One lead",
        "description": "Needs the leads:read scope.",
        "operationId": "GetLead",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Lead"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/v1/leads/{id}/status": {
      "post": {
        "tags": [
          "Leads"
        ],
        "summary": "Move a lead, as the Leads page does",
        "description": "New to Contacted and back, to Archived from any, and an archived lead restored to Contacted. A lead becomes Converted only by becoming a client. Needs the leads:write scope.",
        "operationId": "ChangeLeadStatus",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LeadStatusChange"
              }
            }
          },
          "required": true
        },
        "responses": {
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Lead"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "422": {
            "description": "Unprocessable Entity",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/v1/appointments": {
      "get": {
        "tags": [
          "Appointments"
        ],
        "summary": "The business's appointments, a page at a time, oldest booked first",
        "description": "Narrow to dates from and to, inclusive, on the business's own calendar. Cancelled appointments are left out unless includeCancelled is true. updatedSince returns only the appointments booked, changed or cancelled at or after that instant. Needs the appointments:read scope.",
        "operationId": "ListAppointments",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          },
          {
            "name": "pageSize",
            "in": "query",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          },
          {
            "name": "updatedSince",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "from",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "to",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "includeCancelled",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PageOfAppointment"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Appointments"
        ],
        "summary": "Book an appointment against one of the business's jobs or clients",
        "description": "On the business's own clock and its calendar, with its reminders and, when asked, its email to the client. Send an Idempotency-Key to make a retry safe. Needs the appointments:write scope.",
        "operationId": "CreateAppointment",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/NewAppointment"
              }
            }
          },
          "required": true
        },
        "responses": {
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Appointment"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "422": {
            "description": "Unprocessable Entity",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/v1/appointments/{id}": {
      "get": {
        "tags": [
          "Appointments"
        ],
        "summary": "One appointment",
        "description": "Needs the appointments:read scope.",
        "operationId": "GetAppointment",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Appointment"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Appointments"
        ],
        "summary": "Reschedule an appointment, or change its details",
        "description": "A field left out is left as it is; an empty string clears the location or the notes; allDay true drops the times. Needs the appointments:write scope.",
        "operationId": "UpdateAppointment",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AppointmentChanges"
              }
            }
          },
          "required": true
        },
        "responses": {
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Appointment"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "422": {
            "description": "Unprocessable Entity",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/v1/appointments/{id}/cancel": {
      "post": {
        "tags": [
          "Appointments"
        ],
        "summary": "Cancel an appointment",
        "description": "It stays on record as cancelled; nothing is deleted. Cancelling a cancelled appointment answers it as it is. Needs the appointments:write scope.",
        "operationId": "CancelAppointment",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Appointment"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/v1/invoices": {
      "get": {
        "tags": [
          "Invoices"
        ],
        "summary": "The business's invoices, with their lines, payments and balance, a page at a time",
        "description": "Narrow by status, clientId and jobId. updatedSince returns only the invoices raised or changed at or after that instant. Nothing on v1 writes an invoice. Needs the invoices:read scope.",
        "operationId": "ListInvoices",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          },
          {
            "name": "pageSize",
            "in": "query",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          },
          {
            "name": "updatedSince",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "clientId",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "jobId",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PageOfInvoice"
                }
              }
            }
          }
        }
      }
    },
    "/v1/invoices/{id}": {
      "get": {
        "tags": [
          "Invoices"
        ],
        "summary": "One invoice, with its lines, payments and balance",
        "description": "Needs the invoices:read scope.",
        "operationId": "GetInvoice",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Invoice"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/v1/webhooks/events": {
      "get": {
        "tags": [
          "Webhooks"
        ],
        "summary": "The events a subscription may be sent, with the fields each carries",
        "operationId": "ListWebhookEvents",
        "responses": {
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/WebhookEvent"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/webhooks": {
      "get": {
        "tags": [
          "Webhooks"
        ],
        "summary": "The subscriptions this key made",
        "description": "Only this key's: a subscription a person or another key made is theirs. Needs the webhooks:write scope.",
        "operationId": "ListWebhooks",
        "responses": {
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Webhook"
                  }
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Webhooks"
        ],
        "summary": "Subscribe an address to events",
        "description": "The console's rules: an https address on the public internet, events from the catalog, at most ten subscriptions per business; the address is checked again before every delivery. The signing secret is in this answer and never again. Send an Idempotency-Key to make a retry safe. Needs the webhooks:write scope.",
        "operationId": "CreateWebhook",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/NewWebhook"
              }
            }
          },
          "required": true
        },
        "responses": {
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreatedWebhook"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "422": {
            "description": "Unprocessable Entity",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/v1/webhooks/{id}": {
      "delete": {
        "tags": [
          "Webhooks"
        ],
        "summary": "Remove a subscription this key made",
        "description": "Nothing already sent is recalled. A subscription the key did not make is not found. Needs the webhooks:write scope.",
        "operationId": "DeleteWebhook",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "204": {
            "description": "No Content"
          },
          "404": {
            "description": "Not Found",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Appointment": {
        "required": [
          "id",
          "title",
          "date",
          "startTime",
          "endTime",
          "allDay",
          "start",
          "end",
          "location",
          "notes",
          "jobId",
          "clientId",
          "reminderEnabled",
          "cancelled",
          "createdAt",
          "updatedAt",
          "cancelledAt"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "title": {
            "type": "string"
          },
          "date": {
            "type": "string",
            "format": "date"
          },
          "startTime": {
            "type": [
              "null",
              "string"
            ],
            "format": "time"
          },
          "endTime": {
            "type": [
              "null",
              "string"
            ],
            "format": "time"
          },
          "allDay": {
            "type": "boolean"
          },
          "start": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          },
          "end": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          },
          "location": {
            "type": [
              "null",
              "string"
            ]
          },
          "notes": {
            "type": [
              "null",
              "string"
            ]
          },
          "jobId": {
            "type": [
              "null",
              "string"
            ],
            "format": "uuid"
          },
          "clientId": {
            "type": [
              "null",
              "string"
            ],
            "format": "uuid"
          },
          "reminderEnabled": {
            "type": "boolean",
            "description": "Whether the client is sent a reminder before the visit."
          },
          "cancelled": {
            "type": "boolean"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          },
          "cancelledAt": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          }
        }
      },
      "AppointmentChanges": {
        "required": [
          "title",
          "date",
          "startTime",
          "endTime",
          "allDay",
          "location",
          "notes",
          "reminderEnabled"
        ],
        "type": "object",
        "properties": {
          "title": {
            "type": [
              "null",
              "string"
            ]
          },
          "date": {
            "type": [
              "null",
              "string"
            ],
            "format": "date"
          },
          "startTime": {
            "type": [
              "null",
              "string"
            ],
            "format": "time"
          },
          "endTime": {
            "type": [
              "null",
              "string"
            ],
            "format": "time"
          },
          "allDay": {
            "type": [
              "null",
              "boolean"
            ]
          },
          "location": {
            "type": [
              "null",
              "string"
            ]
          },
          "notes": {
            "type": [
              "null",
              "string"
            ]
          },
          "reminderEnabled": {
            "type": [
              "null",
              "boolean"
            ]
          }
        }
      },
      "Business": {
        "required": [
          "id",
          "name"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          }
        }
      },
      "Client": {
        "required": [
          "id",
          "name",
          "businessName",
          "email",
          "phone",
          "address",
          "notes",
          "archived",
          "source",
          "sourceLabel",
          "createdAt",
          "updatedAt"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "businessName": {
            "type": [
              "null",
              "string"
            ]
          },
          "email": {
            "type": [
              "null",
              "string"
            ]
          },
          "phone": {
            "type": [
              "null",
              "string"
            ]
          },
          "address": {
            "type": [
              "null",
              "string"
            ]
          },
          "notes": {
            "type": [
              "null",
              "string"
            ]
          },
          "archived": {
            "type": "boolean",
            "description": "Archived clients are hidden from the business's lists and are listed here only when asked for."
          },
          "source": {
            "type": "string",
            "description": "The door the client came through, such as Integration, PublicPageDirect or Manual."
          },
          "sourceLabel": {
            "type": [
              "null",
              "string"
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          }
        }
      },
      "ClientChanges": {
        "required": [
          "name",
          "businessName",
          "email",
          "phone",
          "address",
          "notes"
        ],
        "type": "object",
        "properties": {
          "name": {
            "type": [
              "null",
              "string"
            ]
          },
          "businessName": {
            "type": [
              "null",
              "string"
            ]
          },
          "email": {
            "type": [
              "null",
              "string"
            ]
          },
          "phone": {
            "type": [
              "null",
              "string"
            ]
          },
          "address": {
            "type": [
              "null",
              "string"
            ]
          },
          "notes": {
            "type": [
              "null",
              "string"
            ]
          }
        }
      },
      "CreatedWebhook": {
        "required": [
          "webhook",
          "secret"
        ],
        "type": "object",
        "properties": {
          "webhook": {
            "$ref": "#/components/schemas/Webhook"
          },
          "secret": {
            "type": "string",
            "description": "Verifies each delivery's X-SmgTools-Signature: t=<timestamp>,v1=<hex>, where v1 is HMAC-SHA256 of <timestamp>.<body> under this secret."
          }
        }
      },
      "Invoice": {
        "required": [
          "id",
          "number",
          "clientId",
          "jobId",
          "status",
          "issueDate",
          "dueDate",
          "lines",
          "subtotal",
          "taxRate",
          "tax",
          "total",
          "amountPaid",
          "balance",
          "payments",
          "customerReference",
          "notes",
          "sentAt",
          "paidAt",
          "voidedAt",
          "createdAt",
          "updatedAt"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "number": {
            "type": "string",
            "description": "The invoice's number in the business, such as INV-0042."
          },
          "clientId": {
            "type": "string",
            "format": "uuid"
          },
          "jobId": {
            "type": [
              "null",
              "string"
            ],
            "format": "uuid"
          },
          "status": {
            "type": "string",
            "description": "Draft, Sent, Viewed, PartiallyPaid, Paid, Overdue or Voided."
          },
          "issueDate": {
            "type": "string",
            "description": "The date printed on the invoice.",
            "format": "date"
          },
          "dueDate": {
            "type": [
              "null",
              "string"
            ],
            "format": "date"
          },
          "lines": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/InvoiceLine"
            }
          },
          "subtotal": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "format": "double"
          },
          "taxRate": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "type": [
              "null",
              "number",
              "string"
            ],
            "description": "The tax rate as a percentage, such as 8.25; null when the invoice is not taxed.",
            "format": "double"
          },
          "tax": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "format": "double"
          },
          "total": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "format": "double"
          },
          "amountPaid": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "description": "Everything paid, tips excluded.",
            "format": "double"
          },
          "balance": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "description": "What is still owed: the total less what has been paid.",
            "format": "double"
          },
          "payments": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Payment"
            }
          },
          "customerReference": {
            "type": [
              "null",
              "string"
            ]
          },
          "notes": {
            "type": [
              "null",
              "string"
            ]
          },
          "sentAt": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          },
          "paidAt": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          },
          "voidedAt": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          }
        }
      },
      "InvoiceLine": {
        "required": [
          "description",
          "quantity",
          "unitPrice",
          "hours",
          "hourlyRate",
          "total"
        ],
        "type": "object",
        "properties": {
          "description": {
            "type": "string"
          },
          "quantity": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "type": [
              "null",
              "number",
              "string"
            ],
            "format": "double"
          },
          "unitPrice": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "type": [
              "null",
              "number",
              "string"
            ],
            "format": "double"
          },
          "hours": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "type": [
              "null",
              "number",
              "string"
            ],
            "format": "double"
          },
          "hourlyRate": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "type": [
              "null",
              "number",
              "string"
            ],
            "format": "double"
          },
          "total": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "format": "double"
          }
        }
      },
      "Job": {
        "required": [
          "id",
          "number",
          "clientId",
          "jobTypeId",
          "title",
          "description",
          "status",
          "startDate",
          "targetCompletionDate",
          "actualCompletionDate",
          "billingBasis",
          "agreedPrice",
          "location",
          "priority",
          "notes",
          "customerReference",
          "archived",
          "createdAt",
          "updatedAt"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "number": {
            "type": "string",
            "description": "The job's number in the business, such as J-0042."
          },
          "clientId": {
            "type": "string",
            "format": "uuid"
          },
          "jobTypeId": {
            "type": "string",
            "format": "uuid"
          },
          "title": {
            "type": "string"
          },
          "description": {
            "type": [
              "null",
              "string"
            ]
          },
          "status": {
            "type": "string",
            "description": "One of Planning, Approved, InProgress, OnHold, EnRoute, OnSite, Completed, Closed. EnRoute and OnSite are the crew's to report."
          },
          "startDate": {
            "type": [
              "null",
              "string"
            ],
            "format": "date"
          },
          "targetCompletionDate": {
            "type": [
              "null",
              "string"
            ],
            "format": "date"
          },
          "actualCompletionDate": {
            "type": [
              "null",
              "string"
            ],
            "format": "date"
          },
          "billingBasis": {
            "type": [
              "null",
              "string"
            ],
            "description": "AgreedPrice, AsItGoes, or null when the business has not said."
          },
          "agreedPrice": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "type": [
              "null",
              "number",
              "string"
            ],
            "description": "The price agreed for the job, when it is billed at one.",
            "format": "double"
          },
          "location": {
            "type": [
              "null",
              "string"
            ]
          },
          "priority": {
            "type": [
              "null",
              "string"
            ],
            "description": "Low, Medium, High or Urgent."
          },
          "notes": {
            "type": [
              "null",
              "string"
            ]
          },
          "customerReference": {
            "type": [
              "null",
              "string"
            ],
            "description": "The customer's own reference for the work — a purchase order, a work order."
          },
          "archived": {
            "type": "boolean"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          }
        }
      },
      "JobChanges": {
        "required": [
          "clientId",
          "title",
          "description",
          "number",
          "jobTypeId",
          "startDate",
          "targetCompletionDate",
          "agreedPrice",
          "location",
          "priority",
          "notes",
          "customerReference"
        ],
        "type": "object",
        "properties": {
          "clientId": {
            "type": [
              "null",
              "string"
            ],
            "format": "uuid"
          },
          "title": {
            "type": [
              "null",
              "string"
            ]
          },
          "description": {
            "type": [
              "null",
              "string"
            ]
          },
          "number": {
            "type": [
              "null",
              "string"
            ]
          },
          "jobTypeId": {
            "type": [
              "null",
              "string"
            ],
            "format": "uuid"
          },
          "startDate": {
            "type": [
              "null",
              "string"
            ],
            "format": "date"
          },
          "targetCompletionDate": {
            "type": [
              "null",
              "string"
            ],
            "format": "date"
          },
          "agreedPrice": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "type": [
              "null",
              "number",
              "string"
            ],
            "format": "double"
          },
          "location": {
            "type": [
              "null",
              "string"
            ]
          },
          "priority": {
            "type": [
              "null",
              "string"
            ]
          },
          "notes": {
            "type": [
              "null",
              "string"
            ]
          },
          "customerReference": {
            "type": [
              "null",
              "string"
            ]
          }
        }
      },
      "JobStatusChange": {
        "required": [
          "status",
          "actualCompletionDate",
          "checklistOverrideReason"
        ],
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "description": "Planning, Approved, InProgress, OnHold, Completed or Closed."
          },
          "actualCompletionDate": {
            "type": [
              "null",
              "string"
            ],
            "description": "When it was finished, for Completed; today in the business's time zone when left out.",
            "format": "date"
          },
          "checklistOverrideReason": {
            "type": [
              "null",
              "string"
            ],
            "description": "Why the job may be finished with its checklist incomplete. Refused without one while anything required is outstanding."
          }
        }
      },
      "Key": {
        "required": [
          "id",
          "name",
          "scopes"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "scopes": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "Lead": {
        "required": [
          "id",
          "name",
          "email",
          "phone",
          "address",
          "descriptionOfWork",
          "preferredContactMethod",
          "preferredTimeOfDay",
          "preferredDate",
          "preferredTimeWindow",
          "source",
          "sourceLabel",
          "status",
          "clientId",
          "createdAt",
          "contactedAt",
          "convertedAt",
          "archivedAt"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "email": {
            "type": [
              "null",
              "string"
            ]
          },
          "phone": {
            "type": [
              "null",
              "string"
            ]
          },
          "address": {
            "type": [
              "null",
              "string"
            ]
          },
          "descriptionOfWork": {
            "type": [
              "null",
              "string"
            ]
          },
          "preferredContactMethod": {
            "type": [
              "null",
              "string"
            ]
          },
          "preferredTimeOfDay": {
            "type": [
              "null",
              "string"
            ]
          },
          "preferredDate": {
            "type": [
              "null",
              "string"
            ],
            "format": "date"
          },
          "preferredTimeWindow": {
            "type": [
              "null",
              "string"
            ]
          },
          "source": {
            "type": "string",
            "description": "The door the lead came through, such as Integration, PublicPageDirect, Referral or InboundCall."
          },
          "sourceLabel": {
            "type": [
              "null",
              "string"
            ],
            "description": "What that door was called — for a lead a key made, the key's name."
          },
          "status": {
            "type": "string",
            "description": "New, Contacted, Converted or Archived."
          },
          "clientId": {
            "type": [
              "null",
              "string"
            ],
            "description": "The client the lead became, or belongs to.",
            "format": "uuid"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "contactedAt": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          },
          "convertedAt": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          },
          "archivedAt": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          }
        }
      },
      "LeadStatusChange": {
        "required": [
          "status"
        ],
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "description": "New, Contacted or Archived."
          }
        }
      },
      "Me": {
        "required": [
          "business",
          "key"
        ],
        "type": "object",
        "properties": {
          "business": {
            "$ref": "#/components/schemas/Business"
          },
          "key": {
            "$ref": "#/components/schemas/Key"
          }
        }
      },
      "NewAppointment": {
        "required": [
          "title",
          "date",
          "startTime",
          "endTime",
          "allDay",
          "location",
          "notes",
          "jobId",
          "clientId",
          "reminderEnabled",
          "notifyClient"
        ],
        "type": "object",
        "properties": {
          "title": {
            "type": "string"
          },
          "date": {
            "type": "string",
            "format": "date"
          },
          "startTime": {
            "type": [
              "null",
              "string"
            ],
            "description": "Needed unless allDay is true.",
            "format": "time"
          },
          "endTime": {
            "type": [
              "null",
              "string"
            ],
            "description": "An hour after the start when left out.",
            "format": "time"
          },
          "allDay": {
            "type": "boolean"
          },
          "location": {
            "type": [
              "null",
              "string"
            ]
          },
          "notes": {
            "type": [
              "null",
              "string"
            ]
          },
          "jobId": {
            "type": [
              "null",
              "string"
            ],
            "format": "uuid"
          },
          "clientId": {
            "type": [
              "null",
              "string"
            ],
            "format": "uuid"
          },
          "reminderEnabled": {
            "type": [
              "null",
              "boolean"
            ],
            "description": "Left out, true."
          },
          "notifyClient": {
            "type": [
              "null",
              "boolean"
            ],
            "description": "Send the client an email that the visit is booked. Left out, false."
          }
        }
      },
      "NewClient": {
        "required": [
          "name",
          "businessName",
          "email",
          "phone",
          "address",
          "notes"
        ],
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "businessName": {
            "type": [
              "null",
              "string"
            ]
          },
          "email": {
            "type": [
              "null",
              "string"
            ]
          },
          "phone": {
            "type": [
              "null",
              "string"
            ]
          },
          "address": {
            "type": [
              "null",
              "string"
            ]
          },
          "notes": {
            "type": [
              "null",
              "string"
            ]
          }
        }
      },
      "NewJob": {
        "required": [
          "clientId",
          "title",
          "description",
          "number",
          "jobTypeId",
          "status",
          "startDate",
          "targetCompletionDate",
          "agreedPrice",
          "location",
          "priority",
          "notes",
          "customerReference"
        ],
        "type": "object",
        "properties": {
          "clientId": {
            "type": "string",
            "format": "uuid"
          },
          "title": {
            "type": "string"
          },
          "description": {
            "type": [
              "null",
              "string"
            ]
          },
          "number": {
            "type": [
              "null",
              "string"
            ],
            "description": "Left out, the business's next number is given."
          },
          "jobTypeId": {
            "type": [
              "null",
              "string"
            ],
            "description": "Left out, the business's default job type.",
            "format": "uuid"
          },
          "status": {
            "type": [
              "null",
              "string"
            ],
            "description": "Left out, Planning. EnRoute and OnSite are the crew's to report and are refused."
          },
          "startDate": {
            "type": [
              "null",
              "string"
            ],
            "format": "date"
          },
          "targetCompletionDate": {
            "type": [
              "null",
              "string"
            ],
            "format": "date"
          },
          "agreedPrice": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "type": [
              "null",
              "number",
              "string"
            ],
            "format": "double"
          },
          "location": {
            "type": [
              "null",
              "string"
            ]
          },
          "priority": {
            "type": [
              "null",
              "string"
            ]
          },
          "notes": {
            "type": [
              "null",
              "string"
            ]
          },
          "customerReference": {
            "type": [
              "null",
              "string"
            ]
          }
        }
      },
      "NewLead": {
        "required": [
          "name",
          "email",
          "phone",
          "address",
          "descriptionOfWork",
          "preferredContactMethod",
          "preferredTimeOfDay",
          "preferredDate",
          "preferredTimeWindow"
        ],
        "type": "object",
        "properties": {
          "name": {
            "type": [
              "null",
              "string"
            ]
          },
          "email": {
            "type": [
              "null",
              "string"
            ]
          },
          "phone": {
            "type": [
              "null",
              "string"
            ]
          },
          "address": {
            "type": [
              "null",
              "string"
            ]
          },
          "descriptionOfWork": {
            "type": [
              "null",
              "string"
            ]
          },
          "preferredContactMethod": {
            "type": [
              "null",
              "string"
            ],
            "description": "Email, Phone or Text."
          },
          "preferredTimeOfDay": {
            "type": [
              "null",
              "string"
            ],
            "description": "Morning, Afternoon or Evening."
          },
          "preferredDate": {
            "type": [
              "null",
              "string"
            ],
            "format": "date"
          },
          "preferredTimeWindow": {
            "type": [
              "null",
              "string"
            ]
          }
        }
      },
      "NewWebhook": {
        "required": [
          "url",
          "events"
        ],
        "type": "object",
        "properties": {
          "url": {
            "type": "string"
          },
          "events": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "PageOfAppointment": {
        "required": [
          "data",
          "page",
          "pageSize",
          "total"
        ],
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Appointment"
            }
          },
          "page": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "pageSize": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "total": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int64"
          }
        }
      },
      "PageOfClient": {
        "required": [
          "data",
          "page",
          "pageSize",
          "total"
        ],
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Client"
            }
          },
          "page": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "pageSize": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "total": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int64"
          }
        }
      },
      "PageOfInvoice": {
        "required": [
          "data",
          "page",
          "pageSize",
          "total"
        ],
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Invoice"
            }
          },
          "page": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "pageSize": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "total": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int64"
          }
        }
      },
      "PageOfJob": {
        "required": [
          "data",
          "page",
          "pageSize",
          "total"
        ],
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Job"
            }
          },
          "page": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "pageSize": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "total": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int64"
          }
        }
      },
      "PageOfLead": {
        "required": [
          "data",
          "page",
          "pageSize",
          "total"
        ],
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Lead"
            }
          },
          "page": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "pageSize": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "total": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int64"
          }
        }
      },
      "Payment": {
        "required": [
          "id",
          "amount",
          "tip",
          "method",
          "receivedAt",
          "voided"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "amount": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "format": "double"
          },
          "tip": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "description": "A tip given with the payment, on top of the amount.",
            "format": "double"
          },
          "method": {
            "type": "string",
            "description": "How it was paid, such as Card, Cash, Check or BankTransfer."
          },
          "receivedAt": {
            "type": "string",
            "format": "date-time"
          },
          "voided": {
            "type": "boolean",
            "description": "A voided payment no longer counts toward what is paid."
          }
        }
      },
      "Problem": {
        "required": [
          "status",
          "code",
          "title"
        ],
        "type": "object",
        "properties": {
          "status": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "code": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "scope": {
            "type": [
              "null",
              "string"
            ]
          },
          "errors": {
            "type": [
              "null",
              "object"
            ],
            "additionalProperties": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          }
        }
      },
      "Webhook": {
        "required": [
          "id",
          "url",
          "events",
          "status",
          "createdAt"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "url": {
            "type": "string"
          },
          "events": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "The events it is sent, by name from the catalog at /v1/webhooks/events."
          },
          "status": {
            "type": "string",
            "description": "Active; Paused, when the platform stopped after failed deliveries and the business has to resume it; or Disabled."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "WebhookEvent": {
        "required": [
          "name",
          "description",
          "fields"
        ],
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "fields": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      }
    },
    "securitySchemes": {
      "apiKey": {
        "type": "http",
        "description": "An API key the business issued on its Integrations page.",
        "scheme": "bearer",
        "bearerFormat": "smgk_"
      }
    }
  },
  "security": [
    {
      "apiKey": [ ]
    }
  ],
  "tags": [
    {
      "name": "Me"
    },
    {
      "name": "Clients"
    },
    {
      "name": "Jobs"
    },
    {
      "name": "Leads"
    },
    {
      "name": "Appointments"
    },
    {
      "name": "Invoices"
    },
    {
      "name": "Webhooks"
    }
  ]
}