{
  "openapi": "3.0.3",
  "info": {
    "title": "WaysteStar application API",
    "version": "2026-10-11",
    "description": "Selected, source-reviewed read endpoints of the current application API. Not a versioned public partner API or complete API schema. No API-key or machine-to-machine authentication contract is provided."
  },
  "servers": [
    {
      "url": "https://waystestar.com",
      "description": "Default app origin; replace with your assigned WaysteStar app origin."
    }
  ],
  "paths": {
    "/api/health": {
      "get": {
        "operationId": "Checkservicehealth",
        "summary": "Check service health",
        "description": "Public operational health. Returns status, uptime in milliseconds, uptimeHuman, database status, scheduler state and timestamp. HTTP 503 signals database failure; HTTP 500 signals an unexpected health-check failure. A scheduler task error can report degraded with HTTP 200.",
        "tags": [
          "Service"
        ],
        "security": [],
        "parameters": [],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "description": "Application record. Fields may evolve; this initial reference does not define a complete record schema."
                }
              }
            }
          },
          "400": {
            "description": "Invalid request (where validated)"
          },
          "429": {
            "description": "Rate limited; inspect Retry-After"
          },
          "500": {
            "description": "Unexpected server error"
          },
          "503": {
            "description": "Database unavailable"
          }
        }
      }
    },
    "/api/customers": {
      "get": {
        "operationId": "Listcustomers",
        "summary": "List customers",
        "description": "Returns a bare array of company customer records. A page is not the entire customer directory. Use the directory endpoint for server-side search and a matching total. Requires customers view or full access (admins bypass section checks).",
        "tags": [
          "Customers"
        ],
        "security": [
          {
            "clerkSession": []
          }
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "description": "Positive page size; defaults to 500 and is capped at 500. Use integer values.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 500,
              "default": 500
            }
          },
          {
            "name": "offset",
            "in": "query",
            "description": "Rows to skip; defaults to zero.",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "additionalProperties": true,
                    "description": "Application record. Fields may evolve; this initial reference does not define a complete record schema."
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid request (where validated)"
          },
          "401": {
            "description": "Authentication required"
          },
          "403": {
            "description": "Permission or account restriction"
          },
          "429": {
            "description": "Rate limited; inspect Retry-After"
          },
          "500": {
            "description": "Unexpected server error"
          }
        }
      }
    },
    "/api/customers/directory": {
      "get": {
        "operationId": "Searchthecustomerdirectory",
        "summary": "Search the customer directory",
        "description": "Returns { rows, total, limit, offset }. Search and filters apply across the company directory before pagination. archived=only selects archived accounts; other values use live accounts. status and type are optional filters; all disables either filter. Additional sort and field selectors are validated by the server; consult the app for supported values. Requires customers view or full access (admins bypass section checks).",
        "tags": [
          "Customers"
        ],
        "security": [
          {
            "clerkSession": []
          }
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "description": "Positive page size; defaults to 500 and is capped at 500. Use integer values.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 500,
              "default": 500
            }
          },
          {
            "name": "offset",
            "in": "query",
            "description": "Rows to skip; defaults to zero.",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            }
          },
          {
            "name": "search",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "type",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "archived",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "live",
                "only"
              ],
              "default": "live"
            }
          },
          {
            "name": "dir",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "desc"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "rows",
                    "total",
                    "limit",
                    "offset"
                  ],
                  "properties": {
                    "rows": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": true,
                        "description": "Application record. Fields may evolve; this initial reference does not define a complete record schema."
                      }
                    },
                    "total": {
                      "type": "integer"
                    },
                    "limit": {
                      "type": "number"
                    },
                    "offset": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid request (where validated)"
          },
          "401": {
            "description": "Authentication required"
          },
          "403": {
            "description": "Permission or account restriction"
          },
          "429": {
            "description": "Rate limited; inspect Retry-After"
          },
          "500": {
            "description": "Unexpected server error"
          }
        }
      }
    },
    "/api/customers/{id}": {
      "get": {
        "operationId": "Getacustomer",
        "summary": "Get a customer",
        "description": "Returns one company customer record. Missing records return HTTP 404 with message Customer not found. Requires customers view or full access (admins bypass section checks).",
        "tags": [
          "Customers"
        ],
        "security": [
          {
            "clerkSession": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Record ID within the authenticated company.",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "description": "Application record. Fields may evolve; this initial reference does not define a complete record schema."
                }
              }
            }
          },
          "400": {
            "description": "Invalid request (where validated)"
          },
          "401": {
            "description": "Authentication required"
          },
          "403": {
            "description": "Permission or account restriction"
          },
          "404": {
            "description": "Record not found"
          },
          "429": {
            "description": "Rate limited; inspect Retry-After"
          },
          "500": {
            "description": "Unexpected server error"
          }
        }
      }
    },
    "/api/routes": {
      "get": {
        "operationId": "Listroutes",
        "summary": "List routes",
        "description": "Returns a bare array of company routes. This handler does not use the shared limit/offset pagination helper. Requires routes view or full access (admins bypass section checks).",
        "tags": [
          "Routing"
        ],
        "security": [
          {
            "clerkSession": []
          }
        ],
        "parameters": [],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "additionalProperties": true,
                    "description": "Application record. Fields may evolve; this initial reference does not define a complete record schema."
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid request (where validated)"
          },
          "401": {
            "description": "Authentication required"
          },
          "403": {
            "description": "Permission or account restriction"
          },
          "429": {
            "description": "Rate limited; inspect Retry-After"
          },
          "500": {
            "description": "Unexpected server error"
          }
        }
      }
    },
    "/api/routes/{id}": {
      "get": {
        "operationId": "Getaroute",
        "summary": "Get a route",
        "description": "Returns one company route. Missing records return HTTP 404 with message Route not found. Requires routes view or full access (admins bypass section checks).",
        "tags": [
          "Routing"
        ],
        "security": [
          {
            "clerkSession": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Record ID within the authenticated company.",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "description": "Application record. Fields may evolve; this initial reference does not define a complete record schema."
                }
              }
            }
          },
          "400": {
            "description": "Invalid request (where validated)"
          },
          "401": {
            "description": "Authentication required"
          },
          "403": {
            "description": "Permission or account restriction"
          },
          "404": {
            "description": "Record not found"
          },
          "429": {
            "description": "Rate limited; inspect Retry-After"
          },
          "500": {
            "description": "Unexpected server error"
          }
        }
      }
    },
    "/api/work-orders": {
      "get": {
        "operationId": "Listworkorders",
        "summary": "List work orders",
        "description": "Returns a bare array of work orders. Without date, limit/offset pagination applies. With date, there is no default 500-row cap: the entire day is returned unless you explicitly set limit. The date-filtered branch ignores offset; do not use it to page a day. Requires dispatch view or full access (admins bypass section checks).",
        "tags": [
          "Dispatch"
        ],
        "security": [
          {
            "clerkSession": []
          }
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "description": "Positive page size; defaults to 500 and is capped at 500. Use integer values.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 500,
              "default": 500
            }
          },
          {
            "name": "offset",
            "in": "query",
            "description": "Rows to skip; defaults to zero.",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            }
          },
          {
            "name": "date",
            "in": "query",
            "description": "Scheduled day (YYYY-MM-DD). With date supplied, the handler returns the entire day unless an explicit limit is supplied; offset is not applied to the date-filtered branch.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "additionalProperties": true,
                    "description": "Application record. Fields may evolve; this initial reference does not define a complete record schema."
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid request (where validated)"
          },
          "401": {
            "description": "Authentication required"
          },
          "403": {
            "description": "Permission or account restriction"
          },
          "429": {
            "description": "Rate limited; inspect Retry-After"
          },
          "500": {
            "description": "Unexpected server error"
          }
        }
      }
    },
    "/api/vehicles": {
      "get": {
        "operationId": "Listvehicles",
        "summary": "List vehicles",
        "description": "Returns a bare array of company vehicle records using limit/offset pagination. Requires vehicles view or full access (admins bypass section checks).",
        "tags": [
          "Fleet"
        ],
        "security": [
          {
            "clerkSession": []
          }
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "description": "Positive page size; defaults to 500 and is capped at 500. Use integer values.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 500,
              "default": 500
            }
          },
          {
            "name": "offset",
            "in": "query",
            "description": "Rows to skip; defaults to zero.",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "additionalProperties": true,
                    "description": "Application record. Fields may evolve; this initial reference does not define a complete record schema."
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid request (where validated)"
          },
          "401": {
            "description": "Authentication required"
          },
          "403": {
            "description": "Permission or account restriction"
          },
          "429": {
            "description": "Rate limited; inspect Retry-After"
          },
          "500": {
            "description": "Unexpected server error"
          }
        }
      }
    },
    "/api/invoices": {
      "get": {
        "operationId": "Listinvoices",
        "summary": "List invoices",
        "description": "Returns a bare array of company invoice records using limit/offset pagination. This is the list endpoint, not the joined invoice grid. Requires invoices view or full access (admins bypass section checks).",
        "tags": [
          "Billing"
        ],
        "security": [
          {
            "clerkSession": []
          }
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "description": "Positive page size; defaults to 500 and is capped at 500. Use integer values.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 500,
              "default": 500
            }
          },
          {
            "name": "offset",
            "in": "query",
            "description": "Rows to skip; defaults to zero.",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "additionalProperties": true,
                    "description": "Application record. Fields may evolve; this initial reference does not define a complete record schema."
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid request (where validated)"
          },
          "401": {
            "description": "Authentication required"
          },
          "403": {
            "description": "Permission or account restriction"
          },
          "429": {
            "description": "Rate limited; inspect Retry-After"
          },
          "500": {
            "description": "Unexpected server error"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "clerkSession": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT",
        "description": "Short-lived Clerk session token for a provisioned staff user. Never use a Clerk secret key."
      }
    }
  }
}
