{"openapi":"3.1.0","info":{"title":"Complytio API","version":"1.0.202609","summary":"Authenticated food-safety compliance API for UK hospitality.","description":"Complytio exposes authenticated customer APIs powering the web dashboard and native mobile app.\n\n- Every endpoint enforces server-side tenant isolation (company + branch) and granular permissions.\n- The accepted permissions for each operation are declared in the `x-required-permissions` extension.\n- There is no anonymous/public data access and no public OAuth authorization server yet.\n- Human overview: https://www.complytio.com/api.md — agent index: https://www.complytio.com/llms.txt","contact":{"name":"Complytio support","url":"https://www.complytio.com/contact"},"license":{"name":"Proprietary","url":"https://www.complytio.com/terms"}},"servers":[{"url":"https://www.complytio.com","description":"Production"}],"tags":[{"name":"tasks","description":"Daily checks and task instances"},{"name":"documents","description":"Document metadata"},{"name":"eho","description":"EHO visit records"},{"name":"reports","description":"Reporting statistics"}],"components":{"securitySchemes":{"customerSession":{"type":"apiKey","in":"cookie","name":"authjs.session-token","description":"Authenticated Complytio web session cookie issued after login (Auth.js/JWT)."},"mobileBearer":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"Short-lived access token issued by the mobile login flow.\nObtain via POST /api/mobile/auth/login, refresh via POST /api/mobile/auth/refresh.\nFor Google, Apple, email-code or passkey sign-in, the native app exchanges the single-use web handoff code via POST /api/mobile/auth/exchange.\nGoogle/Apple sign-in tokens are NOT valid against these endpoints."}},"schemas":{"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}},"TaskSummary":{"type":"object","description":"Branch-scoped task instance (subset of persisted fields).","properties":{"id":{"type":"string"},"title":{"type":"string"},"category":{"type":"string"},"status":{"type":"string","enum":["pending","in_progress","completed","missed","overdue"]},"dueAt":{"type":"string","format":"date-time","nullable":true},"scheduledFor":{"type":"string","nullable":true},"timeSlots":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"time":{"type":"string"}}}},"metadata":{"type":"object","additionalProperties":true}}},"DocumentSummary":{"type":"object","description":"Document metadata record (file bytes are never exposed here).","properties":{"id":{"type":"string"},"name":{"type":"string"},"category":{"type":"string"},"branchId":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}}}}},"security":[{"customerSession":[]},{"mobileBearer":[]}],"paths":{"/api/tasks":{"get":{"tags":["tasks"],"operationId":"listTasks","summary":"List compliance checks (tasks)","description":"Lists branch-scoped task instances for the authenticated company.\n\n- Default view returns current/pending work; `view=today` returns the grouped task board for one branch (requires `branchId`).\n- `history=true` reads completed/missed history between optional date bounds.\n- Results are capped by `limit` (max 200).","security":[{"customerSession":[]},{"mobileBearer":[]}],"parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["pending","in_progress","completed","missed","overdue"]},"description":"Filter by task status."},{"name":"branchId","in":"query","required":false,"schema":{"type":"string"},"description":"Branch to scope results to. Required for view=today."},{"name":"limit","in":"query","required":false,"schema":{"type":"string"},"description":"Maximum tasks to return (1–200, default 100)."},{"name":"includeCompleted","in":"query","required":false,"schema":{"type":"string"},"description":"Include completed instances in the default view."},{"name":"history","in":"query","required":false,"schema":{"type":"string"},"description":"Return completed/missed history instead of active work."},{"name":"historyFrom","in":"query","required":false,"schema":{"type":"string"},"description":"History window start (ISO-8601 date)."},{"name":"historyTo","in":"query","required":false,"schema":{"type":"string"},"description":"History window end (ISO-8601 date)."},{"name":"completedFrom","in":"query","required":false,"schema":{"type":"string"},"description":"Completed-window start (ISO-8601 date)."},{"name":"completedTo","in":"query","required":false,"schema":{"type":"string"},"description":"Completed-window end (ISO-8601 date)."}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","required":["tasks"],"properties":{"tasks":{"type":"array","items":{"$ref":"#/components/schemas/TaskSummary"}}}}}}},"401":{"description":"Missing or expired credentials","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}},"402":{"description":"Company account is not active (billing required)","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}},"403":{"description":"Authenticated but lacking the required branch/permission scope","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}},"429":{"description":"Rate limit exceeded. Includes Retry-After and RateLimit-* headers.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}},"RateLimit-Limit":{"description":"Request quota for the window.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Remaining requests in the window.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}},"500":{"description":"Unexpected server error","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}}},"x-required-permissions":["tasks:read","checks:view"]}},"/api/tasks/{id}":{"get":{"tags":["tasks"],"operationId":"getTask","summary":"Read one task instance","description":"Returns a single branch-scoped task instance with its fields and responses.","security":[{"customerSession":[]},{"mobileBearer":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Task instance id."}],"responses":{"200":{"description":"The task instance","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaskSummary"}}}},"401":{"description":"Missing or expired credentials","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}},"402":{"description":"Company account is not active (billing required)","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}},"403":{"description":"Authenticated but lacking the required branch/permission scope","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}},"404":{"description":"Task not found in the authorised branches","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}},"429":{"description":"Rate limit exceeded. Includes Retry-After and RateLimit-* headers.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}},"RateLimit-Limit":{"description":"Request quota for the window.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Remaining requests in the window.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}},"500":{"description":"Unexpected server error","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}}},"x-required-permissions":["tasks:read","checks:view"]},"patch":{"tags":["tasks"],"operationId":"updateTaskStatus","summary":"Start or complete a task instance","description":"Progresses an authorised task instance (e.g. start, submit responses, complete).\nRequires the task-complete permission scope; completed tasks are immutable.","security":[{"customerSession":[]},{"mobileBearer":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Task instance id."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true},"description":"Task-specific field responses and status transition payload."}}},"responses":{"200":{"description":"The task instance","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaskSummary"}}}},"401":{"description":"Missing or expired credentials","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}},"402":{"description":"Company account is not active (billing required)","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}},"403":{"description":"Authenticated but lacking the required branch/permission scope","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}},"404":{"description":"Task not found in the authorised branches","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}},"429":{"description":"Rate limit exceeded. Includes Retry-After and RateLimit-* headers.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}},"RateLimit-Limit":{"description":"Request quota for the window.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Remaining requests in the window.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}},"500":{"description":"Unexpected server error","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}}},"x-required-permissions":["tasks:complete","checks:complete"]}},"/api/documents":{"get":{"tags":["documents"],"operationId":"listDocuments","summary":"List document metadata","description":"Lists branch-scoped document metadata for the authenticated company. File bytes are only served through guarded, audited document routes.","security":[{"customerSession":[]},{"mobileBearer":[]}],"parameters":[{"name":"branchId","in":"query","required":false,"schema":{"type":"string"},"description":"Branch to scope results to."},{"name":"category","in":"query","required":false,"schema":{"type":"string"},"description":"Filter by document category."},{"name":"limit","in":"query","required":false,"schema":{"type":"string"},"description":"Maximum documents to return."}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","required":["documents"],"properties":{"documents":{"type":"array","items":{"$ref":"#/components/schemas/DocumentSummary"}}}}}}},"401":{"description":"Missing or expired credentials","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}},"402":{"description":"Company account is not active (billing required)","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}},"403":{"description":"Authenticated but lacking the required branch/permission scope","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}},"429":{"description":"Rate limit exceeded. Includes Retry-After and RateLimit-* headers.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}},"RateLimit-Limit":{"description":"Request quota for the window.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Remaining requests in the window.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}},"500":{"description":"Unexpected server error","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}}},"x-required-permissions":["documents:view","documents:read"]}},"/api/eho":{"get":{"tags":["eho"],"operationId":"listEhoVisits","summary":"List EHO visit records","description":"Lists Environmental Health Officer visit records scoped to the authenticated company and branches.","security":[{"customerSession":[]},{"mobileBearer":[]}],"parameters":[{"name":"branchId","in":"query","required":false,"schema":{"type":"string"},"description":"Branch to scope results to."}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"visits":{"type":"array","items":{"type":"object"}}}}}}},"401":{"description":"Missing or expired credentials","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}},"402":{"description":"Company account is not active (billing required)","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}},"403":{"description":"Authenticated but lacking the required branch/permission scope","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}},"429":{"description":"Rate limit exceeded. Includes Retry-After and RateLimit-* headers.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}},"RateLimit-Limit":{"description":"Request quota for the window.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Remaining requests in the window.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}},"500":{"description":"Unexpected server error","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}}},"x-required-permissions":["eho:view","eho:read","evidence_pack:view"]}},"/api/reports/stats":{"get":{"tags":["reports"],"operationId":"getReportStats","summary":"Read reporting statistics","description":"Branch-scoped compliance reporting statistics for dashboards. Rate limited to 5 requests per minute per user.","security":[{"customerSession":[]},{"mobileBearer":[]}],"parameters":[{"name":"branchId","in":"query","required":false,"schema":{"type":"string"},"description":"Branch to scope statistics to."}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"401":{"description":"Missing or expired credentials","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}},"402":{"description":"Company account is not active (billing required)","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}},"403":{"description":"Authenticated but lacking the required branch/permission scope","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}},"429":{"description":"Rate limit exceeded. Includes Retry-After and RateLimit-* headers.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}},"RateLimit-Limit":{"description":"Request quota for the window.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Remaining requests in the window.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}},"500":{"description":"Unexpected server error","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}}},"x-required-permissions":["reports:read","analytics:view","evidence_pack:view"]}}},"x-scopes-supported":["checks:view","tasks:read","checks:complete","tasks:complete","documents:view","documents:read","eho:view","eho:read","evidence_pack:view","reports:read","analytics:view"],"externalDocs":{"description":"Developer portal","url":"https://www.complytio.com/developers"}}