{
  "openapi": "3.0.3",
  "info": {
    "title": "Requidex Open API",
    "version": "1.0.0",
    "description": "Read-only external API for workforce and programme data. Versioned and isolated from internal APIs.\n\n## Authentication\n\nAll requests must include a Bearer API key in the `Authorization` header:\n\n```\nAuthorization: Bearer <API_KEY>\n```\n\n## Company scope\n\nAll list endpoints accept an optional `company` query parameter to scope results to a specific company.\n\nIf omitted, data for **all companies linked to the API key** is returned.\n\nTo filter to a single company, pass its id:\n\n```\nGET /api/open/v1/projects?company=<COMPANY_ID>\n```\n\nThe company ID must match one of the companies the API key is authorised for.\n\nMaster API keys are not linked to specific companies and must always supply the `company` parameter."
  },
  "servers": [
    {
      "url": "/api/open/v1",
      "description": "Open API v1"
    }
  ],
  "components": {
    "securitySchemes": {
      "BearerApiKey": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "API Key",
        "description": "Authorization: Bearer <API_KEY>"
      }
    },
    "schemas": {
      "EntityReference": {
        "type": "object",
        "nullable": true,
        "required": ["id", "name"],
        "properties": {
          "id": {
            "type": "string",
            "nullable": true,
            "description": "Entity id",
            "example": "67bc36db80a1616ec3f47001"
          },
          "name": {
            "type": "string",
            "description": "Entity name",
            "example": "Requidex Construction Ltd"
          }
        }
      },
      "PhoneNumber": {
        "type": "object",
        "nullable": true,
        "required": ["countryCode", "number"],
        "properties": {
          "countryCode": {
            "type": "string",
            "description": "Country dialing code",
            "example": "+44"
          },
          "number": {
            "type": "string",
            "description": "Phone number",
            "example": "1234567890"
          }
        }
      },
      "Address": {
        "type": "object",
        "nullable": true,
        "description": "Address details",
        "properties": {
          "lineOne": {
            "type": "string",
            "description": "Address line one",
            "example": "1 Builder Way"
          },
          "lineTwo": {
            "type": "string",
            "description": "Address line two",
            "example": "Floor 2"
          },
          "city": {
            "type": "string",
            "description": "City",
            "example": "London"
          },
          "region": {
            "type": "string",
            "description": "Region",
            "example": "Greater London"
          },
          "country": {
            "type": "string",
            "description": "Country",
            "example": "United Kingdom"
          },
          "code": {
            "type": "string",
            "description": "Postal code",
            "example": "EC1A 1BB"
          },
          "latitude": {
            "type": "number",
            "description": "Latitude",
            "example": 51.5074
          },
          "longitude": {
            "type": "number",
            "description": "Longitude",
            "example": -0.1278
          },
          "formattedAddress": {
            "type": "string",
            "nullable": true,
            "description": "Full formatted address",
            "example": "1 Builder Way, Floor 2, London, Greater London, EC1A 1BB"
          }
        }
      },
      "CompanyFinance": {
        "type": "object",
        "nullable": true,
        "description": "Company finance settings",
        "additionalProperties": true
      },
      "CompanyConfig": {
        "type": "object",
        "nullable": true,
        "description": "Company configuration object. Returned only when `includeConfig=true`.",
        "additionalProperties": true
      },
      "ProjectConfig": {
        "type": "object",
        "nullable": true,
        "description": "Project configuration object. Returned only when `includeConfig=true`.",
        "additionalProperties": true,
        "properties": {
          "inheritCompanyFinance": {
            "type": "boolean",
            "description": "Whether project finance inherits from the company"
          },
          "inheritCompanyBilling": {
            "type": "boolean",
            "description": "Whether project billing inherits from the company"
          },
          "autoAssign": {
            "type": "boolean",
            "description": "Whether auto-assignment is enabled"
          },
          "useUplifts": {
            "type": "boolean",
            "description": "Whether project uplift rules override company uplift rules"
          },
          "rateUplifts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ProjectRateUplift"
            }
          },
          "timesheetAdjustment": {
            "$ref": "#/components/schemas/ProjectTimesheetAdjustment"
          },
          "enhancedUplifts": {
            "$ref": "#/components/schemas/ProjectEnhancedUpliftsConfig"
          },
          "workingRuleAgreement": {
            "$ref": "#/components/schemas/ProjectWorkingRuleAgreement"
          }
        }
      },
      "ProjectRateUplift": {
        "type": "object",
        "properties": {
          "description": {
            "type": "string",
            "nullable": true,
            "description": "Uplift label"
          },
          "type": {
            "type": "string",
            "nullable": true,
            "description": "Uplift type key"
          },
          "uplift": {
            "type": "number",
            "nullable": true,
            "description": "Uplift percentage"
          }
        }
      },
      "ProjectTimesheetAdjustment": {
        "type": "object",
        "nullable": true,
        "properties": {
          "project": {
            "type": "boolean"
          },
          "supplier": {
            "type": "boolean"
          }
        }
      },
      "ProjectEnhancedUpliftBlock": {
        "type": "object",
        "properties": {
          "startHour": {
            "type": "number",
            "nullable": true
          },
          "endHour": {
            "type": "number",
            "nullable": true
          },
          "upliftPercentage": {
            "type": "number",
            "nullable": true
          }
        }
      },
      "ProjectEnhancedUpliftShift": {
        "type": "object",
        "nullable": true,
        "properties": {
          "startTime": {
            "type": "number",
            "nullable": true
          },
          "breakAssumption": {
            "type": "number",
            "nullable": true
          },
          "blocks": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ProjectEnhancedUpliftBlock"
            }
          }
        }
      },
      "ProjectEnhancedUpliftDay": {
        "type": "object",
        "nullable": true,
        "properties": {
          "enabled": {
            "type": "boolean"
          },
          "dayShift": {
            "$ref": "#/components/schemas/ProjectEnhancedUpliftShift"
          },
          "nightShift": {
            "$ref": "#/components/schemas/ProjectEnhancedUpliftShift"
          }
        }
      },
      "ProjectEnhancedUpliftDays": {
        "type": "object",
        "nullable": true,
        "properties": {
          "mon": {
            "$ref": "#/components/schemas/ProjectEnhancedUpliftDay"
          },
          "tue": {
            "$ref": "#/components/schemas/ProjectEnhancedUpliftDay"
          },
          "wed": {
            "$ref": "#/components/schemas/ProjectEnhancedUpliftDay"
          },
          "thu": {
            "$ref": "#/components/schemas/ProjectEnhancedUpliftDay"
          },
          "fri": {
            "$ref": "#/components/schemas/ProjectEnhancedUpliftDay"
          },
          "sat": {
            "$ref": "#/components/schemas/ProjectEnhancedUpliftDay"
          },
          "sun": {
            "$ref": "#/components/schemas/ProjectEnhancedUpliftDay"
          },
          "bankHol": {
            "$ref": "#/components/schemas/ProjectEnhancedUpliftDay"
          }
        }
      },
      "ProjectEnhancedUpliftWeekly": {
        "type": "object",
        "nullable": true,
        "properties": {
          "threshold": {
            "type": "number",
            "nullable": true,
            "description": "Weekly hours threshold"
          },
          "enforce": {
            "type": "boolean",
            "description": "Whether the threshold must be worked before uplifts apply"
          },
          "reduce": {
            "type": "boolean",
            "description": "Whether authorised absences reduce the threshold"
          }
        }
      },
      "ProjectEnhancedUpliftsConfig": {
        "type": "object",
        "nullable": true,
        "properties": {
          "enabled": {
            "type": "boolean",
            "description": "Whether enhanced uplifts are enabled"
          },
          "mode": {
            "type": "string",
            "nullable": true,
            "description": "Enhanced uplift calculation mode"
          },
          "weekly": {
            "$ref": "#/components/schemas/ProjectEnhancedUpliftWeekly"
          },
          "days": {
            "$ref": "#/components/schemas/ProjectEnhancedUpliftDays"
          }
        }
      },
      "ProjectWorkingRuleAgreement": {
        "type": "object",
        "nullable": true,
        "properties": {
          "enabled": {
            "type": "boolean"
          },
          "accommodation": {
            "type": "object",
            "nullable": true,
            "description": "Accommodation settings including dailyAmount, absence flags, preferredLabel, showInTotalsSeparately, and nested lodge settings",
            "additionalProperties": true
          }
        }
      },
      "QualificationReference": {
        "type": "object",
        "required": ["name"],
        "properties": {
          "name": {
            "type": "string",
            "description": "Qualification name"
          }
        }
      },
      "CompetencyRequirementGroup": {
        "type": "object",
        "required": ["items"],
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/QualificationReference"
            }
          }
        }
      },
      "CompetencyRequirement": {
        "type": "object",
        "required": ["rule", "items", "groups"],
        "properties": {
          "rule": {
            "type": "string",
            "description": "Requirement rule",
            "example": "mandatory"
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/QualificationReference"
            }
          },
          "groups": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CompetencyRequirementGroup"
            }
          }
        }
      },
      "CompetencyMatrixTrade": {
        "type": "object",
        "nullable": true,
        "required": ["id", "name"],
        "properties": {
          "id": {
            "type": "string",
            "nullable": true,
            "description": "Trade id"
          },
          "name": {
            "type": "string",
            "description": "Trade name"
          }
        }
      },
      "CompetencyMatrixEntry": {
        "type": "object",
        "required": ["trade", "sector", "requirements"],
        "properties": {
          "trade": {
            "$ref": "#/components/schemas/CompetencyMatrixTrade"
          },
          "sector": {
            "$ref": "#/components/schemas/EntityReference"
          },
          "requirements": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CompetencyRequirement"
            }
          }
        }
      },
      "TradeCompetencyMatrixEntry": {
        "type": "object",
        "required": ["sector", "requirements"],
        "properties": {
          "sector": {
            "$ref": "#/components/schemas/EntityReference"
          },
          "requirements": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CompetencyRequirement"
            }
          }
        }
      },
      "CompanyCompetencyMatrixPayload": {
        "type": "object",
        "required": ["company", "entries"],
        "properties": {
          "company": {
            "$ref": "#/components/schemas/EntityReference"
          },
          "entries": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CompetencyMatrixEntry"
            }
          }
        }
      },
      "CompanyCompetencyMatrixResponse": {
        "type": "object",
        "required": ["success", "data"],
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "data": {
            "$ref": "#/components/schemas/CompanyCompetencyMatrixPayload"
          }
        }
      },
      "Project": {
        "type": "object",
        "required": ["id", "nanoid", "name", "createdAt", "updatedAt"],
        "properties": {
          "id": {
            "type": "string",
            "description": "Project id",
            "example": "67bc36db80a1616ec3f4739e"
          },
          "nanoid": {
            "type": "string",
            "description": "Short project id",
            "example": "abc123def4"
          },
          "name": {
            "type": "string",
            "description": "Project name",
            "example": "Northern Rail Electrification"
          },
          "code": {
            "type": "string",
            "description": "Project code",
            "example": "NRE-001"
          },
          "email": {
            "type": "string",
            "description": "Project contact email",
            "example": "pm@requidex.com"
          },
          "phone": {
            "$ref": "#/components/schemas/PhoneNumber"
          },
          "active": {
            "type": "boolean",
            "description": "Whether project is active",
            "example": true
          },
          "singleSite": {
            "type": "boolean",
            "description": "Whether project is single-site",
            "example": false
          },
          "siteCount": {
            "type": "integer",
            "description": "Number of sites linked to project",
            "example": 3
          },
          "company": {
            "$ref": "#/components/schemas/EntityReference"
          },
          "region": {
            "$ref": "#/components/schemas/EntityReference"
          },
          "sector": {
            "$ref": "#/components/schemas/EntityReference"
          },
          "dates": {
            "type": "object",
            "description": "Optional project date window",
            "properties": {
              "start": {
                "type": "string",
                "format": "date-time"
              },
              "end": {
                "type": "string",
                "format": "date-time"
              }
            }
          },
          "config": {
            "$ref": "#/components/schemas/ProjectConfig"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "description": "Creation timestamp"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time",
            "description": "Last update timestamp"
          }
        }
      },
      "ApiKeyInfo": {
        "type": "object",
        "required": [
          "name",
          "scopes",
          "rateLimitPerMinute",
          "rateLimitPerDay",
          "usage",
          "companies",
          "createdAt"
        ],
        "properties": {
          "name": {
            "type": "string",
            "description": "API key name",
            "example": "Data Warehouse Sync"
          },
          "description": {
            "type": "string",
            "description": "Optional description for this API key",
            "example": "Used for nightly ETL pipeline"
          },
          "scopes": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Scopes granted to this API key. Purchase orders require `read:purchase-orders`, workers require `read:workers`, and credit notes require `read:credit-notes`.",
            "example": [
              "read:companies",
              "read:trades",
              "read:rates",
              "read:projects",
              "read:workers",
              "read:purchase-orders",
              "read:invoices",
              "read:credit-notes"
            ]
          },
          "rateLimitPerMinute": {
            "type": "integer",
            "description": "Maximum requests allowed per minute",
            "example": 60
          },
          "rateLimitPerDay": {
            "type": "integer",
            "description": "Maximum requests allowed per day (UTC)",
            "example": 5000
          },
          "ipAllowlist": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Allowed IP addresses or CIDR ranges. Empty means no restriction.",
            "example": ["203.0.113.0/24"]
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Expiry timestamp, or null if the key does not expire",
            "example": "2027-01-01T00:00:00.000Z"
          },
          "lastUsedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Timestamp of the most recent request made with this key",
            "example": "2026-03-16T09:30:00.000Z"
          },
          "usage": {
            "type": "object",
            "required": ["requestsToday", "remainingToday", "resetsAt"],
            "description": "Daily usage for this API key in the current UTC day window",
            "properties": {
              "requestsToday": {
                "type": "integer",
                "description": "Requests recorded so far today",
                "example": 127
              },
              "remainingToday": {
                "type": "integer",
                "description": "Remaining requests available today before the daily cap is reached",
                "example": 4873
              },
              "resetsAt": {
                "type": "string",
                "format": "date-time",
                "description": "Timestamp when the daily usage window resets (midnight UTC)",
                "example": "2026-03-17T00:00:00.000Z"
              }
            }
          },
          "companies": {
            "type": "array",
            "description": "Companies this key is linked to. Empty for master keys.",
            "items": {
              "$ref": "#/components/schemas/EntityReference"
            }
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "description": "Timestamp this key was created"
          }
        }
      },
      "ApiKeyInfoResponse": {
        "type": "object",
        "required": ["success", "data"],
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "data": {
            "$ref": "#/components/schemas/ApiKeyInfo"
          }
        }
      },
      "Company": {
        "type": "object",
        "required": ["id", "name", "createdAt", "updatedAt"],
        "properties": {
          "id": {
            "type": "string",
            "description": "Company id",
            "example": "67bc36db80a1616ec3f47001"
          },
          "name": {
            "type": "string",
            "description": "Company name",
            "example": "Requidex Construction Ltd"
          },
          "prefix": {
            "type": "string",
            "nullable": true,
            "description": "Company prefix used for reference generation",
            "example": "RCL"
          },
          "email": {
            "type": "string",
            "nullable": true,
            "description": "Company contact email",
            "example": "hello@requidex.com"
          },
          "phone": {
            "$ref": "#/components/schemas/PhoneNumber"
          },
          "companyNumber": {
            "type": "string",
            "nullable": true,
            "description": "Registered company number",
            "example": "12345678"
          },
          "active": {
            "type": "boolean",
            "description": "Whether the company is active",
            "example": true
          },
          "projectCount": {
            "type": "integer",
            "description": "Number of projects linked to this company",
            "example": 12
          },
          "address": {
            "$ref": "#/components/schemas/Address"
          },
          "finance": {
            "$ref": "#/components/schemas/CompanyFinance"
          },
          "config": {
            "$ref": "#/components/schemas/CompanyConfig"
          },
          "industry": {
            "type": "string",
            "nullable": true,
            "description": "Industry sector",
            "enum": [
              "construction",
              "education",
              "healthcare",
              "facilities_management",
              "hospitality",
              "manufacturing",
              "transport_and_logistics",
              "utilities",
              "waste_management"
            ],
            "example": "construction"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "description": "Creation timestamp"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time",
            "description": "Last update timestamp"
          }
        }
      },
      "CompaniesListResponse": {
        "type": "object",
        "required": ["success", "data", "meta"],
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Company"
            }
          },
          "meta": {
            "$ref": "#/components/schemas/PaginationMeta"
          }
        }
      },
      "CompanyResponse": {
        "type": "object",
        "required": ["success", "data"],
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "data": {
            "$ref": "#/components/schemas/Company"
          }
        }
      },
      "ConnectedAgencyCisStatus": {
        "type": "object",
        "nullable": true,
        "properties": {
          "name": {
            "type": "string",
            "nullable": true
          },
          "value": {
            "type": "number",
            "nullable": true
          },
          "display": {
            "type": "string",
            "nullable": true
          }
        }
      },
      "ConnectedAgencyPaymentTerms": {
        "type": "object",
        "nullable": true,
        "properties": {
          "days": {
            "type": "number",
            "nullable": true
          },
          "term": {
            "type": "string",
            "nullable": true
          }
        }
      },
      "ConnectedAgencyRateUpliftRegion": {
        "type": "object",
        "required": ["id", "name", "uplift"],
        "properties": {
          "id": {
            "type": "string",
            "nullable": true
          },
          "name": {
            "type": "string"
          },
          "uplift": {
            "type": "number",
            "nullable": true
          }
        }
      },
      "ConnectedAgencyRateUplift": {
        "type": "object",
        "required": ["description", "type", "uplift", "regions"],
        "properties": {
          "description": {
            "type": "string"
          },
          "type": {
            "type": "string"
          },
          "uplift": {
            "type": "number",
            "nullable": true
          },
          "regions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ConnectedAgencyRateUpliftRegion"
            }
          }
        }
      },
      "ConnectedAgency": {
        "type": "object",
        "required": [
          "id",
          "agency",
          "connectionLevel",
          "cis",
          "tier",
          "restricted",
          "invoice",
          "drc",
          "afp",
          "email",
          "paymentTerms",
          "markupAdjustment",
          "rateUplifts",
          "createdAt",
          "updatedAt"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "Connected-agency record id"
          },
          "agency": {
            "$ref": "#/components/schemas/EntityReference"
          },
          "connectionLevel": {
            "type": "string",
            "enum": ["company", "project"],
            "description": "Whether the connection is defined at company or project level"
          },
          "cis": {
            "$ref": "#/components/schemas/ConnectedAgencyCisStatus"
          },
          "tier": {
            "type": "integer",
            "nullable": true
          },
          "restricted": {
            "type": "boolean",
            "nullable": true
          },
          "invoice": {
            "type": "boolean",
            "nullable": true
          },
          "drc": {
            "type": "boolean",
            "nullable": true
          },
          "afp": {
            "type": "boolean",
            "nullable": true
          },
          "email": {
            "type": "string",
            "nullable": true
          },
          "paymentTerms": {
            "$ref": "#/components/schemas/ConnectedAgencyPaymentTerms"
          },
          "markupAdjustment": {
            "type": "number",
            "nullable": true
          },
          "rateUplifts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ConnectedAgencyRateUplift"
            }
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        }
      },
      "ConnectedAgenciesListResponse": {
        "type": "object",
        "required": ["success", "data", "meta"],
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ConnectedAgency"
            }
          },
          "meta": {
            "$ref": "#/components/schemas/PaginationMeta"
          }
        }
      },
      "Region": {
        "type": "object",
        "required": ["id", "name", "company", "createdAt", "updatedAt"],
        "properties": {
          "id": {
            "type": "string",
            "description": "Region id",
            "example": "67bc36db80a1616ec3f47010"
          },
          "name": {
            "type": "string",
            "description": "Region name",
            "example": "South East"
          },
          "company": {
            "$ref": "#/components/schemas/EntityReference"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "description": "Creation timestamp"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time",
            "description": "Last update timestamp"
          }
        }
      },
      "RegionsListResponse": {
        "type": "object",
        "required": ["success", "data", "meta"],
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Region"
            }
          },
          "meta": {
            "$ref": "#/components/schemas/PaginationMeta"
          }
        }
      },
      "RegionResponse": {
        "type": "object",
        "required": ["success", "data"],
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "data": {
            "$ref": "#/components/schemas/Region"
          }
        }
      },
      "Sector": {
        "type": "object",
        "required": ["id", "name", "company", "createdAt", "updatedAt"],
        "properties": {
          "id": {
            "type": "string",
            "description": "Sector id",
            "example": "67bc36db80a1616ec3f47020"
          },
          "name": {
            "type": "string",
            "description": "Sector name",
            "example": "Commercial"
          },
          "company": {
            "$ref": "#/components/schemas/EntityReference"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "description": "Creation timestamp"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time",
            "description": "Last update timestamp"
          }
        }
      },
      "SectorsListResponse": {
        "type": "object",
        "required": ["success", "data", "meta"],
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Sector"
            }
          },
          "meta": {
            "$ref": "#/components/schemas/PaginationMeta"
          }
        }
      },
      "SectorResponse": {
        "type": "object",
        "required": ["success", "data"],
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "data": {
            "$ref": "#/components/schemas/Sector"
          }
        }
      },
      "MasterTradeReference": {
        "type": "object",
        "nullable": true,
        "required": ["id", "name"],
        "properties": {
          "id": {
            "type": "string",
            "nullable": true,
            "description": "Master trade id"
          },
          "name": {
            "type": "string",
            "description": "Master trade name"
          }
        }
      },
      "TradeTag": {
        "type": "object",
        "required": ["id", "name", "description"],
        "properties": {
          "id": {
            "type": "string",
            "nullable": true,
            "description": "Tag id"
          },
          "name": {
            "type": "string",
            "description": "Tag name"
          },
          "description": {
            "type": "string",
            "description": "Tag description"
          }
        }
      },
      "Trade": {
        "type": "object",
        "required": ["id", "name", "active", "company", "tags", "createdAt", "updatedAt"],
        "properties": {
          "id": {
            "type": "string",
            "description": "Trade id",
            "example": "67bc36db80a1616ec3f47031"
          },
          "name": {
            "type": "string",
            "description": "Trade name",
            "example": "Electrician"
          },
          "description": {
            "type": "string",
            "nullable": true,
            "description": "Trade description",
            "example": "Electrical installation and maintenance"
          },
          "active": {
            "type": "boolean",
            "description": "Whether trade is active",
            "example": true
          },
          "company": {
            "$ref": "#/components/schemas/EntityReference"
          },
          "masterTrade": {
            "$ref": "#/components/schemas/MasterTradeReference"
          },
          "tags": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TradeTag"
            }
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "description": "Creation timestamp"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time",
            "description": "Last update timestamp"
          }
        }
      },
      "TradeRateValue": {
        "type": "object",
        "nullable": true,
        "properties": {
          "pay": {
            "type": "number",
            "nullable": true
          },
          "emp": {
            "type": "number",
            "nullable": true
          },
          "margin": {
            "type": "number",
            "nullable": true
          },
          "charge": {
            "type": "number",
            "nullable": true
          },
          "comparablePayRate": {
            "type": "number",
            "nullable": true
          }
        }
      },
      "TradeRateSet": {
        "type": "object",
        "properties": {
          "cis": {
            "$ref": "#/components/schemas/TradeRateValue"
          },
          "paye": {
            "$ref": "#/components/schemas/TradeRateValue"
          },
          "psc": {
            "$ref": "#/components/schemas/TradeRateValue"
          }
        }
      },
      "TradeRate": {
        "type": "object",
        "required": ["id", "region", "sector", "project", "agency", "rates", "dayRates"],
        "properties": {
          "id": {
            "type": "string",
            "description": "Rate id"
          },
          "region": {
            "$ref": "#/components/schemas/EntityReference"
          },
          "sector": {
            "$ref": "#/components/schemas/EntityReference"
          },
          "project": {
            "$ref": "#/components/schemas/EntityReference"
          },
          "agency": {
            "$ref": "#/components/schemas/EntityReference"
          },
          "rates": {
            "$ref": "#/components/schemas/TradeRateSet"
          },
          "dayRates": {
            "$ref": "#/components/schemas/TradeRateSet"
          }
        }
      },
      "TradeDetail": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Trade"
          },
          {
            "type": "object",
            "properties": {
              "rates": {
                "type": "array",
                "description": "Returned only when `includeRates=true`.",
                "items": {
                  "$ref": "#/components/schemas/TradeRate"
                }
              },
              "competencyMatrix": {
                "type": "array",
                "description": "Returned only when `includeCompetencyMatrix=true`.",
                "items": {
                  "$ref": "#/components/schemas/TradeCompetencyMatrixEntry"
                }
              }
            }
          }
        ]
      },
      "TradesListResponse": {
        "type": "object",
        "required": ["success", "data", "meta"],
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Trade"
            }
          },
          "meta": {
            "$ref": "#/components/schemas/PaginationMeta"
          }
        }
      },
      "TradeResponse": {
        "type": "object",
        "required": ["success", "data"],
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "data": {
            "$ref": "#/components/schemas/TradeDetail"
          }
        }
      },
      "RateRecord": {
        "allOf": [
          {
            "$ref": "#/components/schemas/TradeRate"
          },
          {
            "type": "object",
            "required": ["trade", "company", "createdAt", "updatedAt"],
            "properties": {
              "trade": {
                "$ref": "#/components/schemas/EntityReference"
              },
              "company": {
                "$ref": "#/components/schemas/EntityReference"
              },
              "createdAt": {
                "type": "string",
                "format": "date-time",
                "description": "Creation timestamp"
              },
              "updatedAt": {
                "type": "string",
                "format": "date-time",
                "description": "Last update timestamp"
              }
            }
          }
        ]
      },
      "RatesListResponse": {
        "type": "object",
        "required": ["success", "data", "meta"],
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RateRecord"
            }
          },
          "meta": {
            "$ref": "#/components/schemas/PaginationMeta"
          }
        }
      },
      "PaginationMeta": {
        "type": "object",
        "required": ["page", "limit", "total"],
        "properties": {
          "page": {
            "type": "integer",
            "description": "Current page number",
            "example": 1
          },
          "limit": {
            "type": "integer",
            "description": "Page size used",
            "example": 50
          },
          "total": {
            "type": "integer",
            "description": "Total number of records",
            "example": 2540
          }
        }
      },
      "ProjectsListResponse": {
        "type": "object",
        "required": ["success", "data", "meta"],
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Project"
            }
          },
          "meta": {
            "$ref": "#/components/schemas/PaginationMeta"
          }
        }
      },
      "ProjectResponse": {
        "type": "object",
        "required": ["success", "data"],
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "data": {
            "$ref": "#/components/schemas/Project"
          }
        }
      },
      "Site": {
        "type": "object",
        "required": ["id", "nanoid", "name", "createdAt", "updatedAt"],
        "properties": {
          "id": {
            "type": "string",
            "description": "Site id",
            "example": "67bc36db80a1616ec3f47055"
          },
          "nanoid": {
            "type": "string",
            "description": "Short site id",
            "example": "site12abcd"
          },
          "name": {
            "type": "string",
            "description": "Site name",
            "example": "Manchester Central"
          },
          "project": {
            "$ref": "#/components/schemas/EntityReference"
          },
          "company": {
            "$ref": "#/components/schemas/EntityReference"
          },
          "active": {
            "type": "boolean",
            "description": "Whether site is active",
            "example": true
          },
          "email": {
            "type": "string",
            "description": "Site contact email",
            "example": "site.manager@requidex.com"
          },
          "phone": {
            "$ref": "#/components/schemas/PhoneNumber"
          },
          "address": {
            "$ref": "#/components/schemas/Address"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "description": "Creation timestamp"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time",
            "description": "Last update timestamp"
          }
        }
      },
      "SitesListResponse": {
        "type": "object",
        "required": ["success", "data", "meta"],
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Site"
            }
          },
          "meta": {
            "$ref": "#/components/schemas/PaginationMeta"
          }
        }
      },
      "SiteResponse": {
        "type": "object",
        "required": ["success", "data"],
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "data": {
            "$ref": "#/components/schemas/Site"
          }
        }
      },
      "Requisition": {
        "type": "object",
        "required": ["id", "reference", "status", "createdAt", "updatedAt"],
        "properties": {
          "id": {
            "type": "string",
            "description": "Requisition id",
            "example": "67bc36db80a1616ec3f48123"
          },
          "nanoid": {
            "type": "string",
            "description": "Short requisition id",
            "example": "req01abcde"
          },
          "reference": {
            "type": "string",
            "description": "Requisition reference",
            "example": "REQ-R1002"
          },
          "status": {
            "type": "string",
            "description": "Derived requisition status",
            "enum": ["raised", "approved", "filled", "cancelled", "rejected"],
            "example": "raised"
          },
          "quantity": {
            "type": "number",
            "description": "Requested worker quantity",
            "example": 4
          },
          "company": {
            "$ref": "#/components/schemas/EntityReference"
          },
          "project": {
            "$ref": "#/components/schemas/EntityReference"
          },
          "region": {
            "$ref": "#/components/schemas/EntityReference"
          },
          "sector": {
            "$ref": "#/components/schemas/EntityReference"
          },
          "site": {
            "$ref": "#/components/schemas/EntityReference"
          },
          "trade": {
            "$ref": "#/components/schemas/EntityReference"
          },
          "activity": {
            "$ref": "#/components/schemas/EntityReference"
          },
          "startDate": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Planned start date"
          },
          "endDate": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Planned end date"
          },
          "approvedDate": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Final approval timestamp"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "description": "Creation timestamp"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time",
            "description": "Last update timestamp"
          }
        }
      },
      "RequisitionsListResponse": {
        "type": "object",
        "required": ["success", "data", "meta"],
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Requisition"
            }
          },
          "meta": {
            "$ref": "#/components/schemas/PaginationMeta"
          }
        }
      },
      "RequisitionResponse": {
        "type": "object",
        "required": ["success", "data"],
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "data": {
            "$ref": "#/components/schemas/Requisition"
          }
        }
      },
      "RequisitionLink": {
        "type": "object",
        "nullable": true,
        "required": ["id", "reference", "nanoid"],
        "properties": {
          "id": {
            "type": "string",
            "nullable": true,
            "description": "Requisition id",
            "example": "67bc36db80a1616ec3f48123"
          },
          "reference": {
            "type": "string",
            "description": "Requisition reference",
            "example": "REQ-R1002"
          },
          "nanoid": {
            "type": "string",
            "description": "Short requisition id",
            "example": "req01abcde"
          }
        }
      },
      "WorkerReference": {
        "type": "object",
        "nullable": true,
        "required": ["id", "reference", "name"],
        "properties": {
          "id": {
            "type": "string",
            "nullable": true,
            "description": "Worker id",
            "example": "67bc36db80a1616ec3f48999"
          },
          "reference": {
            "type": "string",
            "description": "Worker reference",
            "example": "WK-1044"
          },
          "name": {
            "type": "string",
            "description": "Worker name",
            "example": "Jordan Smith"
          }
        }
      },
      "UserReference": {
        "type": "object",
        "nullable": true,
        "required": ["id", "name"],
        "properties": {
          "id": {
            "type": "string",
            "nullable": true,
            "description": "User id",
            "example": "67bc36db80a1616ec3f49998"
          },
          "name": {
            "type": "string",
            "description": "User name",
            "example": "Alex Carter"
          }
        }
      },
      "AssignmentAction": {
        "type": "object",
        "nullable": true,
        "properties": {
          "reason": {
            "type": "string",
            "description": "Action reason",
            "example": "Worker unavailable"
          },
          "date": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Action timestamp in ISO 8601 date-time format"
          },
          "comments": {
            "type": "string",
            "description": "Action comments",
            "example": "Cancelled by hirer after site closure"
          },
          "user": {
            "$ref": "#/components/schemas/UserReference"
          }
        }
      },
      "CostCodeReference": {
        "type": "object",
        "nullable": true,
        "properties": {
          "name": {
            "type": "string",
            "description": "Cost code name",
            "example": "CC-001"
          },
          "description": {
            "type": "string",
            "description": "Cost code description",
            "example": "Trackside installation"
          }
        }
      },
      "PayChargeRate": {
        "type": "object",
        "nullable": true,
        "properties": {
          "pay": {
            "type": "number",
            "nullable": true,
            "description": "Pay rate",
            "example": 21.5
          },
          "charge": {
            "type": "number",
            "nullable": true,
            "description": "Charge rate",
            "example": 28.75
          }
        }
      },
      "PayChargeValue": {
        "type": "object",
        "nullable": true,
        "properties": {
          "pay": {
            "type": "number",
            "nullable": true,
            "description": "Pay value",
            "example": 3440
          },
          "charge": {
            "type": "number",
            "nullable": true,
            "description": "Charge value",
            "example": 4600
          }
        }
      },
      "AssignmentRateUplifts": {
        "type": "object",
        "properties": {
          "bh": {
            "type": "number",
            "nullable": true,
            "example": 100
          },
          "bhNw": {
            "type": "number",
            "nullable": true,
            "example": 125
          },
          "wdOt": {
            "type": "number",
            "nullable": true,
            "example": 50
          },
          "sat": {
            "type": "number",
            "nullable": true,
            "example": 50
          },
          "sun": {
            "type": "number",
            "nullable": true,
            "example": 100
          },
          "wdNw": {
            "type": "number",
            "nullable": true,
            "example": 25
          },
          "weNw": {
            "type": "number",
            "nullable": true,
            "example": 40
          }
        }
      },
      "EnhancedUpliftBreakdownItem": {
        "type": "object",
        "properties": {
          "date": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Breakdown row date in ISO 8601 date-time format"
          },
          "dayOfWeek": {
            "type": "string",
            "nullable": true,
            "example": "Monday"
          },
          "shiftType": {
            "type": "string",
            "nullable": true,
            "example": "dayShift"
          },
          "blockStartHour": {
            "type": "number",
            "nullable": true,
            "example": 8
          },
          "blockEndHour": {
            "type": "number",
            "nullable": true,
            "example": 12
          },
          "blockHours": {
            "type": "number",
            "nullable": true,
            "example": 4
          },
          "upliftPercentage": {
            "type": "number",
            "nullable": true,
            "example": 25
          },
          "chargeRate": {
            "type": "number",
            "nullable": true,
            "example": 35.94
          },
          "chargeValue": {
            "type": "number",
            "nullable": true,
            "example": 143.76
          },
          "payRate": {
            "type": "number",
            "nullable": true,
            "example": 26.88
          },
          "payValue": {
            "type": "number",
            "nullable": true,
            "example": 107.52
          }
        }
      },
      "EnhancedUpliftsResponse": {
        "type": "object",
        "properties": {
          "enabled": {
            "type": "boolean",
            "description": "Whether enhanced uplifts are enabled",
            "example": true
          },
          "breakdown": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EnhancedUpliftBreakdownItem"
            }
          }
        }
      },
      "AssignmentDocument": {
        "type": "object",
        "nullable": true,
        "properties": {
          "status": {
            "type": "string",
            "nullable": true,
            "description": "Document status",
            "example": "confirmed"
          },
          "attachment": {
            "type": "string",
            "nullable": true,
            "description": "Attachment URL",
            "example": "https://files.requidex.com/sdc-confirmation.pdf"
          }
        }
      },
      "Assignment": {
        "type": "object",
        "required": ["id", "reference", "status", "createdAt", "updatedAt"],
        "properties": {
          "id": {
            "type": "string",
            "description": "Assignment id",
            "example": "67bc36db80a1616ec3f49001"
          },
          "nanoid": {
            "type": "string",
            "description": "Short assignment id",
            "example": "asg01abcd2"
          },
          "reference": {
            "type": "string",
            "description": "Assignment reference",
            "example": "A1044"
          },
          "status": {
            "type": "string",
            "description": "Assignment status",
            "enum": ["pending", "confirmed", "cancelled", "completed", "ended"],
            "example": "confirmed"
          },
          "payType": {
            "type": "string",
            "nullable": true,
            "description": "Pay type",
            "enum": ["hourly", "daily"],
            "example": "hourly"
          },
          "rateType": {
            "type": "string",
            "nullable": true,
            "description": "Rate type",
            "enum": ["cis", "paye", "psc"],
            "example": "cis"
          },
          "confirmationDate": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Confirmation timestamp in ISO 8601 date-time format"
          },
          "cancellation": {
            "$ref": "#/components/schemas/AssignmentAction"
          },
          "company": {
            "$ref": "#/components/schemas/EntityReference"
          },
          "project": {
            "$ref": "#/components/schemas/EntityReference"
          },
          "region": {
            "$ref": "#/components/schemas/EntityReference"
          },
          "sector": {
            "$ref": "#/components/schemas/EntityReference"
          },
          "site": {
            "$ref": "#/components/schemas/EntityReference"
          },
          "trade": {
            "$ref": "#/components/schemas/EntityReference"
          },
          "agency": {
            "$ref": "#/components/schemas/EntityReference"
          },
          "umbrella": {
            "type": "string",
            "nullable": true,
            "description": "Umbrella company name",
            "example": "UmbrellaCo"
          },
          "worker": {
            "$ref": "#/components/schemas/WorkerReference"
          },
          "workerDistanceToSite": {
            "type": "number",
            "nullable": true,
            "description": "Worker distance to site, in miles",
            "example": 12.4
          },
          "workerLodgeDistanceToSite": {
            "type": "number",
            "nullable": true,
            "description": "Worker lodge distance to site, in miles",
            "example": 4.8
          },
          "requisition": {
            "$ref": "#/components/schemas/RequisitionLink"
          },
          "costCode": {
            "$ref": "#/components/schemas/CostCodeReference"
          },
          "workActivity": {
            "type": "string",
            "nullable": true,
            "description": "Work activity name",
            "example": "Install containment"
          },
          "rates": {
            "$ref": "#/components/schemas/PayChargeRate"
          },
          "values": {
            "$ref": "#/components/schemas/PayChargeValue"
          },
          "rateUplifts": {
            "$ref": "#/components/schemas/AssignmentRateUplifts"
          },
          "enhancedUplifts": {
            "$ref": "#/components/schemas/EnhancedUpliftsResponse"
          },
          "lodgeApplicable": {
            "type": "boolean",
            "description": "Whether lodge/accommodation is applicable on the assignment",
            "example": true
          },
          "weeksElapsed": {
            "type": "integer",
            "description": "Number of full weeks elapsed since confirmation or start date",
            "example": 6
          },
          "purchaseOrder": {
            "type": "string",
            "nullable": true,
            "description": "Purchase order reference",
            "example": "PO-44321"
          },
          "sds": {
            "$ref": "#/components/schemas/AssignmentDocument"
          },
          "sdc": {
            "$ref": "#/components/schemas/AssignmentDocument"
          },
          "kid": {
            "type": "string",
            "nullable": true,
            "description": "KID attachment URL",
            "example": "https://files.requidex.com/kid.pdf"
          },
          "startDate": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Assignment start date in ISO 8601 date-time format"
          },
          "endDate": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Assignment end date in ISO 8601 date-time format"
          },
          "timesheetStartDate": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Timesheet start date in ISO 8601 date-time format"
          },
          "completedDate": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Completion timestamp in ISO 8601 date-time format"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "description": "Creation timestamp in ISO 8601 date-time format"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time",
            "description": "Last update timestamp in ISO 8601 date-time format"
          }
        }
      },
      "AssignmentsListResponse": {
        "type": "object",
        "required": ["success", "data", "meta"],
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Assignment"
            }
          },
          "meta": {
            "$ref": "#/components/schemas/PaginationMeta"
          }
        }
      },
      "AssignmentResponse": {
        "type": "object",
        "required": ["success", "data"],
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "data": {
            "$ref": "#/components/schemas/Assignment"
          }
        }
      },
      "PurchaseOrderStatusChange": {
        "type": "object",
        "nullable": true,
        "properties": {
          "user": {
            "$ref": "#/components/schemas/UserReference"
          },
          "date": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Status-change timestamp in ISO 8601 date-time format"
          }
        }
      },
      "PurchaseOrder": {
        "type": "object",
        "required": [
          "id",
          "status",
          "reference",
          "startDate",
          "endDate",
          "value",
          "company",
          "projects",
          "site",
          "agency",
          "trades",
          "allTrades",
          "tradeOption",
          "createdAt",
          "updatedAt"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "Purchase order id",
            "example": "67bc36db80a1616ec3f48001"
          },
          "status": {
            "type": "string",
            "description": "Purchase order status",
            "enum": ["active", "inactive"]
          },
          "reference": {
            "type": "string",
            "description": "Purchase order reference",
            "example": "PO-44321"
          },
          "startDate": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Purchase order start date in ISO 8601 date-time format"
          },
          "endDate": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Purchase order end date in ISO 8601 date-time format"
          },
          "value": {
            "type": "number",
            "nullable": true,
            "description": "Purchase order value",
            "example": 150000
          },
          "company": {
            "$ref": "#/components/schemas/EntityReference"
          },
          "projects": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EntityReference"
            }
          },
          "site": {
            "$ref": "#/components/schemas/EntityReference"
          },
          "agency": {
            "$ref": "#/components/schemas/EntityReference"
          },
          "trades": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EntityReference"
            }
          },
          "allTrades": {
            "type": "boolean",
            "description": "Whether the purchase order applies to all trades"
          },
          "tradeOption": {
            "type": "string",
            "nullable": true,
            "description": "Trade selection mode",
            "enum": ["all", "specific", "tag"]
          },
          "tag": {
            "description": "Tag reference. Omitted when no tag is set.",
            "$ref": "#/components/schemas/EntityReference"
          },
          "revoked": {
            "description": "Revocation details. Omitted when the purchase order has not been revoked.",
            "$ref": "#/components/schemas/PurchaseOrderStatusChange"
          },
          "reinstated": {
            "description": "Reinstatement details. Omitted when the purchase order has not been reinstated.",
            "$ref": "#/components/schemas/PurchaseOrderStatusChange"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "description": "Creation timestamp in ISO 8601 date-time format"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time",
            "description": "Last update timestamp in ISO 8601 date-time format"
          }
        }
      },
      "PurchaseOrdersListResponse": {
        "type": "object",
        "required": ["success", "data", "meta"],
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PurchaseOrder"
            }
          },
          "meta": {
            "$ref": "#/components/schemas/PaginationMeta"
          }
        }
      },
      "PurchaseOrderResponse": {
        "type": "object",
        "required": ["success", "data"],
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "data": {
            "$ref": "#/components/schemas/PurchaseOrder"
          }
        }
      },
      "TimesheetAssignmentLink": {
        "type": "object",
        "nullable": true,
        "properties": {
          "id": {
            "type": "string",
            "nullable": true,
            "description": "Assignment id",
            "example": "67bc36db80a1616ec3f49001"
          },
          "reference": {
            "type": "string",
            "description": "Assignment reference",
            "example": "A1044"
          }
        }
      },
      "TimesheetWorker": {
        "type": "object",
        "nullable": true,
        "properties": {
          "id": {
            "type": "string",
            "nullable": true,
            "description": "Worker id",
            "example": "67bc36db80a1616ec3f48999"
          },
          "name": {
            "type": "string",
            "description": "Worker name",
            "example": "Jordan Smith"
          }
        }
      },
      "TimesheetValueBreakdown": {
        "type": "object",
        "nullable": true,
        "properties": {
          "wdBasic": {
            "type": "number",
            "nullable": true,
            "example": 860
          },
          "wdOvertime": {
            "type": "number",
            "nullable": true,
            "example": 215
          },
          "wdNightwork": {
            "type": "number",
            "nullable": true,
            "example": 0
          },
          "weNightwork": {
            "type": "number",
            "nullable": true,
            "example": 0
          },
          "bankHoliday": {
            "type": "number",
            "nullable": true,
            "example": 0
          },
          "bankHolidayNight": {
            "type": "number",
            "nullable": true,
            "example": 0
          },
          "saturday": {
            "type": "number",
            "nullable": true,
            "example": 294
          },
          "sunday": {
            "type": "number",
            "nullable": true,
            "example": 295
          },
          "saturdayNightwork": {
            "type": "number",
            "nullable": true,
            "example": 0
          },
          "sundayNightwork": {
            "type": "number",
            "nullable": true,
            "example": 0
          },
          "total": {
            "type": "number",
            "nullable": true,
            "example": 1664
          }
        }
      },
      "TimesheetValueSummary": {
        "type": "object",
        "nullable": true,
        "properties": {
          "pay": {
            "$ref": "#/components/schemas/TimesheetValueBreakdown"
          },
          "charge": {
            "$ref": "#/components/schemas/TimesheetValueBreakdown"
          },
          "expense": {
            "type": "number",
            "nullable": true,
            "example": 125
          }
        }
      },
      "TimesheetCostCodeAllocation": {
        "type": "object",
        "properties": {
          "costCode": {
            "$ref": "#/components/schemas/CostCodeReference"
          },
          "hours": {
            "type": "number",
            "nullable": true,
            "description": "Hours allocated to the cost code",
            "example": 8
          }
        }
      },
      "TimesheetTimelogHours": {
        "type": "object",
        "nullable": true,
        "properties": {
          "standard": {
            "type": "number",
            "nullable": true,
            "example": 8
          },
          "overtime": {
            "type": "number",
            "nullable": true,
            "example": 2
          },
          "total": {
            "type": "number",
            "nullable": true,
            "example": 10
          }
        }
      },
      "TimesheetTimelogRates": {
        "type": "object",
        "nullable": true,
        "properties": {
          "pay": {
            "type": "number",
            "nullable": true,
            "example": 21.5
          },
          "emp": {
            "type": "number",
            "nullable": true,
            "example": 2.93
          },
          "margin": {
            "type": "number",
            "nullable": true,
            "example": 4.32
          },
          "charge": {
            "type": "number",
            "nullable": true,
            "example": 28.75
          }
        }
      },
      "TimesheetTimelogValueBreakdown": {
        "type": "object",
        "nullable": true,
        "properties": {
          "standard": {
            "type": "number",
            "nullable": true,
            "example": 172
          },
          "overtime": {
            "type": "number",
            "nullable": true,
            "example": 43
          },
          "total": {
            "type": "number",
            "nullable": true,
            "example": 215
          }
        }
      },
      "TimesheetTimelogValues": {
        "type": "object",
        "nullable": true,
        "properties": {
          "pay": {
            "$ref": "#/components/schemas/TimesheetTimelogValueBreakdown"
          },
          "emp": {
            "$ref": "#/components/schemas/TimesheetTimelogValueBreakdown"
          },
          "margin": {
            "$ref": "#/components/schemas/TimesheetTimelogValueBreakdown"
          },
          "charge": {
            "$ref": "#/components/schemas/TimesheetTimelogValueBreakdown"
          }
        }
      },
      "TimesheetTimelog": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "nullable": true,
            "description": "Timelog id",
            "example": "67bc36db80a1616ec3f4a101"
          },
          "status": {
            "type": "string",
            "description": "Timelog status",
            "example": "approved"
          },
          "date": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Timelog date in ISO 8601 date-time format"
          },
          "start": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Timelog start in ISO 8601 date-time format"
          },
          "end": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Timelog end in ISO 8601 date-time format"
          },
          "shiftType": {
            "type": "string",
            "nullable": true,
            "description": "Shift type",
            "example": "day"
          },
          "breaks": {
            "type": "number",
            "nullable": true,
            "description": "Break duration in minutes",
            "example": 30
          },
          "rateDescription": {
            "type": "string",
            "nullable": true,
            "description": "Applied rate description",
            "example": "wdBasic"
          },
          "hours": {
            "$ref": "#/components/schemas/TimesheetTimelogHours"
          },
          "rates": {
            "$ref": "#/components/schemas/TimesheetTimelogRates"
          },
          "values": {
            "$ref": "#/components/schemas/TimesheetTimelogValues"
          },
          "absenceAuthorized": {
            "type": "boolean",
            "nullable": true,
            "description": "Whether the timelog absence is authorised",
            "example": false
          },
          "absenceReason": {
            "type": "string",
            "nullable": true,
            "description": "Absence reason",
            "example": "Sick leave"
          },
          "costCodeAllocations": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TimesheetCostCodeAllocation"
            }
          }
        }
      },
      "TimesheetRateSet": {
        "type": "object",
        "nullable": true,
        "properties": {
          "pay": {
            "type": "number",
            "nullable": true,
            "example": 21.5
          },
          "emp": {
            "type": "number",
            "nullable": true,
            "example": 2.93
          },
          "margin": {
            "type": "number",
            "nullable": true,
            "example": 4.32
          },
          "charge": {
            "type": "number",
            "nullable": true,
            "example": 28.75
          },
          "uplift": {
            "type": "number",
            "nullable": true,
            "example": 50
          }
        }
      },
      "TimesheetRates": {
        "type": "object",
        "nullable": true,
        "properties": {
          "wd": {
            "$ref": "#/components/schemas/TimesheetRateSet"
          },
          "wdNw": {
            "$ref": "#/components/schemas/TimesheetRateSet"
          },
          "weNw": {
            "$ref": "#/components/schemas/TimesheetRateSet"
          },
          "bh": {
            "$ref": "#/components/schemas/TimesheetRateSet"
          },
          "bhNight": {
            "$ref": "#/components/schemas/TimesheetRateSet"
          },
          "sat": {
            "$ref": "#/components/schemas/TimesheetRateSet"
          },
          "sun": {
            "$ref": "#/components/schemas/TimesheetRateSet"
          },
          "ot": {
            "$ref": "#/components/schemas/TimesheetRateSet"
          }
        }
      },
      "TimesheetVersionHistory": {
        "type": "object",
        "properties": {
          "version": {
            "type": "integer",
            "description": "Version number, defaults to 1 when missing in stored history data",
            "example": 2
          },
          "snapshotReason": {
            "type": "string",
            "example": "amended"
          },
          "snapshotAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Snapshot timestamp in ISO 8601 date-time format"
          },
          "netHours": {
            "type": "number",
            "nullable": true,
            "example": 37.5
          },
          "expenseValue": {
            "type": "number",
            "nullable": true,
            "example": 125
          },
          "values": {
            "$ref": "#/components/schemas/TimesheetValueSummary"
          },
          "rates": {
            "$ref": "#/components/schemas/TimesheetRates"
          }
        }
      },
      "Timesheet": {
        "type": "object",
        "required": ["id", "reference", "status", "createdAt", "updatedAt"],
        "properties": {
          "id": {
            "type": "string",
            "description": "Timesheet id",
            "example": "67bc36db80a1616ec3f4a001"
          },
          "reference": {
            "type": "string",
            "description": "Timesheet reference",
            "example": "TS-1044"
          },
          "status": {
            "type": "string",
            "description": "Timesheet status",
            "enum": ["pending", "pending_approval", "approved", "cancelled", "absent"],
            "example": "approved"
          },
          "worker": {
            "$ref": "#/components/schemas/TimesheetWorker"
          },
          "assignment": {
            "$ref": "#/components/schemas/TimesheetAssignmentLink"
          },
          "company": {
            "$ref": "#/components/schemas/EntityReference"
          },
          "project": {
            "$ref": "#/components/schemas/EntityReference"
          },
          "site": {
            "$ref": "#/components/schemas/EntityReference"
          },
          "agency": {
            "$ref": "#/components/schemas/EntityReference"
          },
          "payType": {
            "type": "string",
            "nullable": true,
            "description": "Pay type",
            "example": "hourly"
          },
          "rateType": {
            "type": "string",
            "nullable": true,
            "description": "Rate type",
            "example": "cis"
          },
          "start": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Timesheet period start in ISO 8601 date-time format"
          },
          "end": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Timesheet period end in ISO 8601 date-time format"
          },
          "weekEnding": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Week ending date in ISO 8601 date-time format"
          },
          "version": {
            "type": "integer",
            "description": "Current timesheet version number, defaults to 1 when missing or null",
            "example": 2
          },
          "approvedDate": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Approval timestamp in ISO 8601 date-time format"
          },
          "netHours": {
            "type": "number",
            "nullable": true,
            "description": "Total net hours after breaks",
            "example": 37.5
          },
          "rates": {
            "$ref": "#/components/schemas/TimesheetRates"
          },
          "values": {
            "$ref": "#/components/schemas/TimesheetValueSummary"
          },
          "timelogs": {
            "type": "array",
            "description": "Returned only when includeTimelogs=true",
            "items": {
              "$ref": "#/components/schemas/TimesheetTimelog"
            }
          },
          "versionHistory": {
            "type": "array",
            "description": "Returned only on the single-timesheet endpoint when includeVersionHistory=true",
            "items": {
              "$ref": "#/components/schemas/TimesheetVersionHistory"
            }
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "description": "Creation timestamp in ISO 8601 date-time format"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time",
            "description": "Last update timestamp in ISO 8601 date-time format"
          }
        }
      },
      "TimesheetsListResponse": {
        "type": "object",
        "required": ["success", "data", "meta"],
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Timesheet"
            }
          },
          "meta": {
            "$ref": "#/components/schemas/PaginationMeta"
          }
        }
      },
      "TimesheetResponse": {
        "type": "object",
        "required": ["success", "data"],
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "data": {
            "$ref": "#/components/schemas/Timesheet"
          }
        }
      },
      "InvoiceReferenceLink": {
        "type": "object",
        "nullable": true,
        "properties": {
          "id": {
            "type": "string",
            "nullable": true,
            "description": "Invoice id",
            "example": "67bc36db80a1616ec3f4b001"
          },
          "reference": {
            "type": "string",
            "description": "Invoice reference",
            "example": "RDX-NLD-I1044"
          }
        }
      },
      "InvoiceTimesheetLink": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "nullable": true,
            "description": "Timesheet id",
            "example": "67bc36db80a1616ec3f4a001"
          },
          "reference": {
            "type": "string",
            "description": "Timesheet reference",
            "example": "TS-1044"
          }
        }
      },
      "InvoicePaymentSummary": {
        "type": "object",
        "nullable": true,
        "properties": {
          "reference": {
            "type": "string",
            "description": "Payment reference",
            "example": "PAY-2044"
          },
          "paymentDate": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Payment date in ISO 8601 date-time format"
          }
        }
      },
      "InvoiceValueSummary": {
        "type": "object",
        "nullable": true,
        "properties": {
          "grossHours": {
            "type": "number",
            "nullable": true,
            "example": 40
          },
          "netHours": {
            "type": "number",
            "nullable": true,
            "example": 37.5
          },
          "subtotal": {
            "type": "number",
            "nullable": true,
            "example": 1125
          },
          "vat": {
            "type": "number",
            "nullable": true,
            "example": 225
          },
          "total": {
            "type": "number",
            "nullable": true,
            "example": 1350
          },
          "cis": {
            "type": "number",
            "nullable": true,
            "example": 0
          },
          "finalTotal": {
            "type": "number",
            "nullable": true,
            "example": 1350
          },
          "expenses": {
            "type": "number",
            "nullable": true,
            "example": 125
          },
          "creditNotes": {
            "type": "number",
            "nullable": true,
            "example": 0
          },
          "netValue": {
            "type": "number",
            "nullable": true,
            "example": 1475
          }
        }
      },
      "InvoiceFiles": {
        "type": "object",
        "properties": {
          "invoice": {
            "type": "string",
            "nullable": true,
            "description": "Public invoice file URL when available",
            "example": "https://files.requidex.com/invoices/INV-1044.pdf"
          },
          "timesheetSnapshot": {
            "type": "string",
            "nullable": true,
            "description": "Timesheet snapshot file URL when available",
            "example": "https://files.requidex.com/invoices/INV-1044-timesheets.pdf"
          }
        }
      },
      "AfpReferenceLink": {
        "type": "object",
        "nullable": true,
        "properties": {
          "id": {
            "type": "string",
            "nullable": true,
            "description": "AfP id",
            "example": "67bc36db80a1616ec3f4b101"
          },
          "reference": {
            "type": "string",
            "description": "AfP reference",
            "example": "AFP-1044"
          }
        }
      },
      "Invoice": {
        "type": "object",
        "required": ["id", "reference", "status", "createdAt", "updatedAt"],
        "properties": {
          "id": {
            "type": "string",
            "description": "Invoice id",
            "example": "67bc36db80a1616ec3f4b001"
          },
          "reference": {
            "type": "string",
            "description": "Invoice reference",
            "example": "RDX-NLD-I1044"
          },
          "status": {
            "type": "string",
            "description": "Invoice status",
            "enum": ["pending", "confirmed"],
            "example": "pending"
          },
          "company": {
            "$ref": "#/components/schemas/EntityReference"
          },
          "agency": {
            "$ref": "#/components/schemas/EntityReference"
          },
          "msp": {
            "$ref": "#/components/schemas/EntityReference"
          },
          "projects": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EntityReference"
            }
          },
          "invoiceType": {
            "type": "string",
            "nullable": true,
            "enum": ["supplierToClient", "supplierToMsp", "mspToClient"],
            "description": "Invoice flow type",
            "example": "supplierToClient"
          },
          "mspInvoiceType": {
            "type": "string",
            "nullable": true,
            "enum": ["receivable", "payable"],
            "description": "MSP invoice subtype when applicable",
            "example": null
          },
          "weekEnding": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Week ending date in ISO 8601 date-time format"
          },
          "due": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Invoice due date in ISO 8601 date-time format"
          },
          "confirmedDate": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Timestamp when the invoice was marked confirmed/paid"
          },
          "confirmedBy": {
            "$ref": "#/components/schemas/EntityReference"
          },
          "payment": {
            "$ref": "#/components/schemas/InvoicePaymentSummary"
          },
          "values": {
            "$ref": "#/components/schemas/InvoiceValueSummary"
          },
          "files": {
            "$ref": "#/components/schemas/InvoiceFiles"
          },
          "timesheets": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/InvoiceTimesheetLink"
            }
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "description": "Creation timestamp in ISO 8601 date-time format"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time",
            "description": "Last update timestamp in ISO 8601 date-time format"
          }
        }
      },
      "InvoicesListResponse": {
        "type": "object",
        "required": ["success", "data", "meta"],
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Invoice"
            }
          },
          "meta": {
            "$ref": "#/components/schemas/PaginationMeta"
          }
        }
      },
      "InvoiceResponse": {
        "type": "object",
        "required": ["success", "data"],
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "data": {
            "$ref": "#/components/schemas/Invoice"
          }
        }
      },
      "CreditNoteValueSummary": {
        "type": "object",
        "nullable": true,
        "properties": {
          "grossHours": {
            "type": "number",
            "nullable": true,
            "example": 40
          },
          "netHours": {
            "type": "number",
            "nullable": true,
            "example": 37.5
          },
          "subtotal": {
            "type": "number",
            "nullable": true,
            "example": 694.45
          },
          "vat": {
            "type": "number",
            "nullable": true,
            "example": 138.89
          },
          "total": {
            "type": "number",
            "nullable": true,
            "example": 833.34
          },
          "cis": {
            "type": "number",
            "nullable": true,
            "example": 0
          },
          "finalTotal": {
            "type": "number",
            "nullable": true,
            "example": 833.34
          }
        }
      },
      "CreditNoteFiles": {
        "type": "object",
        "properties": {
          "creditNote": {
            "type": "string",
            "nullable": true,
            "description": "Public credit note file URL when available",
            "example": "https://files.requidex.com/credit-notes/CN-12.pdf"
          }
        }
      },
      "CreditNote": {
        "type": "object",
        "required": ["id", "reference", "status", "createdAt", "updatedAt"],
        "properties": {
          "id": {
            "type": "string",
            "description": "Credit note id",
            "example": "67bc36db80a1616ec3f4c001"
          },
          "reference": {
            "type": "string",
            "description": "Credit note reference",
            "example": "RDX-NLD-C12"
          },
          "status": {
            "type": "string",
            "description": "Credit note status",
            "enum": ["pending", "processed"],
            "example": "pending"
          },
          "company": {
            "$ref": "#/components/schemas/EntityReference"
          },
          "agency": {
            "$ref": "#/components/schemas/EntityReference"
          },
          "msp": {
            "$ref": "#/components/schemas/EntityReference"
          },
          "project": {
            "$ref": "#/components/schemas/EntityReference"
          },
          "invoiceType": {
            "type": "string",
            "nullable": true,
            "enum": ["supplierToClient", "supplierToMsp", "mspToClient"],
            "description": "Credit note flow type",
            "example": "supplierToClient"
          },
          "mspInvoiceType": {
            "type": "string",
            "nullable": true,
            "enum": ["receivable", "payable"],
            "description": "MSP credit note subtype when applicable",
            "example": null
          },
          "reason": {
            "type": "string",
            "description": "Credit note reason",
            "example": "Timesheet adjustment"
          },
          "comments": {
            "type": "string",
            "description": "Credit note comments",
            "example": "Adjusted after review"
          },
          "weekEnding": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Returned when present. Week ending date in ISO 8601 date-time format"
          },
          "confirmedDate": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Timestamp when the credit note was marked confirmed/processed"
          },
          "confirmedBy": {
            "$ref": "#/components/schemas/EntityReference"
          },
          "payment": {
            "$ref": "#/components/schemas/InvoicePaymentSummary"
          },
          "values": {
            "$ref": "#/components/schemas/CreditNoteValueSummary"
          },
          "files": {
            "$ref": "#/components/schemas/CreditNoteFiles"
          },
          "invoice": {
            "$ref": "#/components/schemas/InvoiceReferenceLink"
          },
          "timesheet": {
            "$ref": "#/components/schemas/InvoiceTimesheetLink"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "description": "Creation timestamp in ISO 8601 date-time format"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time",
            "description": "Last update timestamp in ISO 8601 date-time format"
          }
        }
      },
      "CreditNotesListResponse": {
        "type": "object",
        "required": ["success", "data", "meta"],
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CreditNote"
            }
          },
          "meta": {
            "$ref": "#/components/schemas/PaginationMeta"
          }
        }
      },
      "CreditNoteResponse": {
        "type": "object",
        "required": ["success", "data"],
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "data": {
            "$ref": "#/components/schemas/CreditNote"
          }
        }
      },
      "PaymentNoticeDisputedItem": {
        "type": "object",
        "properties": {
          "timesheet": {
            "$ref": "#/components/schemas/InvoiceTimesheetLink"
          },
          "expenseId": {
            "type": "string",
            "nullable": true,
            "description": "Disputed expense id when the line relates to an expense",
            "example": "67bc36db80a1616ec3f4c201"
          },
          "amount": {
            "type": "number",
            "nullable": true,
            "description": "Disputed amount for the item",
            "example": 125
          },
          "reason": {
            "type": "string",
            "description": "Reason provided for disputing the item",
            "example": "Hours exceed authorised shift"
          }
        }
      },
      "PaymentNoticeDispute": {
        "type": "object",
        "nullable": true,
        "properties": {
          "comments": {
            "type": "string",
            "description": "Notice-level dispute comments",
            "example": "One timesheet line is disputed pending review."
          },
          "disputedItems": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PaymentNoticeDisputedItem"
            }
          }
        }
      },
      "PaymentNoticeFile": {
        "type": "object",
        "nullable": true,
        "properties": {
          "fileName": {
            "type": "string",
            "description": "Processed notice file name",
            "example": "AFP-1044-payment-notice.pdf"
          },
          "url": {
            "type": "string",
            "nullable": true,
            "description": "Processed notice file URL when available",
            "example": "https://files.requidex.com/payment-notices/AFP-1044-payment-notice.pdf"
          },
          "created": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Timestamp when the processed file was attached"
          }
        }
      },
      "PaymentNotice": {
        "type": "object",
        "required": ["id", "reference", "status", "createdAt", "updatedAt"],
        "properties": {
          "id": {
            "type": "string",
            "description": "Payment notice id",
            "example": "67bc36db80a1616ec3f4d001"
          },
          "reference": {
            "type": "string",
            "description": "Payment notice reference",
            "example": "RDX-NLD-P1044"
          },
          "status": {
            "type": "string",
            "description": "Payment notice status",
            "enum": ["pending", "processed", "cancelled"],
            "example": "pending"
          },
          "afp": {
            "$ref": "#/components/schemas/AfpReferenceLink"
          },
          "company": {
            "$ref": "#/components/schemas/EntityReference"
          },
          "agency": {
            "$ref": "#/components/schemas/EntityReference"
          },
          "approvedAmount": {
            "type": "number",
            "nullable": true,
            "description": "Amount approved by the notice",
            "example": 1225
          },
          "disputedAmount": {
            "type": "number",
            "nullable": true,
            "description": "Amount disputed by the notice",
            "example": 125
          },
          "comments": {
            "type": "string",
            "nullable": true,
            "description": "Free-text comments recorded on the notice",
            "example": "Please see disputed item breakdown."
          },
          "dispute": {
            "$ref": "#/components/schemas/PaymentNoticeDispute"
          },
          "processedDate": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Timestamp when the notice was marked processed"
          },
          "processedFile": {
            "$ref": "#/components/schemas/PaymentNoticeFile"
          },
          "cancellationComments": {
            "type": "string",
            "nullable": true,
            "description": "Cancellation comments when the notice was cancelled",
            "example": "Superseded by corrected notice."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "description": "Creation timestamp in ISO 8601 date-time format"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time",
            "description": "Last update timestamp in ISO 8601 date-time format"
          }
        }
      },
      "PaymentNoticesListResponse": {
        "type": "object",
        "required": ["success", "data", "meta"],
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PaymentNotice"
            }
          },
          "meta": {
            "$ref": "#/components/schemas/PaginationMeta"
          }
        }
      },
      "PaymentNoticeResponse": {
        "type": "object",
        "required": ["success", "data"],
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "data": {
            "$ref": "#/components/schemas/PaymentNotice"
          }
        }
      },
      "ErrorEnvelope": {
        "type": "object",
        "required": ["success", "error"],
        "properties": {
          "success": {
            "type": "boolean",
            "example": false
          },
          "error": {
            "type": "object",
            "required": ["code", "message"],
            "properties": {
              "code": {
                "type": "string",
                "example": "UNAUTHORIZED"
              },
              "message": {
                "type": "string",
                "example": "Invalid API key"
              }
            }
          }
        }
      },
      "WorkerAgency": {
        "type": "object",
        "required": ["id", "name", "agencyId", "active"],
        "properties": {
          "id": {
            "type": "string",
            "nullable": true,
            "description": "Agency id",
            "example": "67bc36db80a1616ec3f47101"
          },
          "name": {
            "type": "string",
            "description": "Agency name",
            "example": "Northline Labour Desk"
          },
          "agencyId": {
            "type": "string",
            "description": "Agency-specific worker identifier",
            "example": "AG-1001"
          },
          "active": {
            "type": "boolean",
            "description": "Whether the worker is active for this agency link",
            "example": true
          }
        }
      },
      "WorkerDocumentFile": {
        "type": "object",
        "required": ["fileName", "url", "docType"],
        "properties": {
          "fileName": {
            "type": "string",
            "description": "Document file name",
            "example": "cscs-front.jpg"
          },
          "url": {
            "type": "string",
            "nullable": true,
            "description": "Public file URL",
            "example": "https://files.requidex.com/cscs-front.jpg"
          },
          "docType": {
            "type": "string",
            "nullable": true,
            "description": "File role within the document set",
            "example": "Front"
          }
        }
      },
      "WorkerDocumentVerificationQualification": {
        "type": "object",
        "required": ["qual"],
        "properties": {
          "qual": {
            "type": "string",
            "description": "Occupation or qualification returned by CSCS Smart Check",
            "example": "Electrician"
          }
        }
      },
      "WorkerDocumentVerification": {
        "type": "object",
        "nullable": true,
        "required": [
          "verified",
          "cardTypeName",
          "serial",
          "customerName",
          "documentNumber",
          "photoType",
          "expiry",
          "occupationQualifications",
          "lastVerifiedAt"
        ],
        "properties": {
          "verified": {
            "type": "boolean",
            "description": "Whether the document passed CSCS Smart Check",
            "example": true
          },
          "cardTypeName": {
            "type": "string",
            "nullable": true,
            "description": "Verified card type name",
            "example": "Gold Skilled Worker"
          },
          "serial": {
            "type": "string",
            "nullable": true,
            "description": "Card serial number",
            "example": "CSCS-SERIAL-1"
          },
          "customerName": {
            "type": "string",
            "nullable": true,
            "description": "Cardholder name returned by CSCS Smart Check",
            "example": "Jordan Smith"
          },
          "documentNumber": {
            "type": "string",
            "nullable": true,
            "description": "Verified card number",
            "example": "CSCS-123"
          },
          "photoType": {
            "type": "string",
            "nullable": true,
            "description": "Cardholder photo content type",
            "example": "image/jpeg"
          },
          "expiry": {
            "type": "string",
            "nullable": true,
            "description": "Verified expiry value",
            "example": "2027-01-01"
          },
          "occupationQualifications": {
            "type": "array",
            "description": "Occupation qualifications returned by CSCS Smart Check",
            "items": {
              "$ref": "#/components/schemas/WorkerDocumentVerificationQualification"
            }
          },
          "lastVerifiedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Timestamp of the latest CSCS Smart Check result"
          }
        }
      },
      "WorkerDocumentSystemValidation": {
        "type": "object",
        "nullable": true,
        "properties": {
          "status": {
            "type": "string",
            "nullable": true,
            "description": "System validation status",
            "example": "validated"
          },
          "checkedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Timestamp of the system validation result"
          },
          "documentType": {
            "type": "string",
            "nullable": true,
            "description": "Document type evaluated by the system validator",
            "example": "CSCS Card"
          },
          "reason": {
            "type": "string",
            "nullable": true,
            "description": "System validation failure reason, when present",
            "example": "illegible"
          }
        }
      },
      "WorkerDocumentValidationStatusHistoryEntry": {
        "type": "object",
        "required": ["status", "changedAt", "changedBy"],
        "properties": {
          "status": {
            "type": "string",
            "nullable": true,
            "description": "Validation status recorded for the history entry",
            "enum": ["validated", "referred", "invalid"],
            "example": "validated"
          },
          "invalidReason": {
            "type": "string",
            "description": "Invalidation reason code when status is invalid",
            "example": "expired"
          },
          "invalidReasonText": {
            "type": "string",
            "description": "Additional invalidation notes when provided",
            "example": "Card expired before assignment start"
          },
          "changedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Timestamp when the history entry was recorded"
          },
          "changedBy": {
            "$ref": "#/components/schemas/UserReference"
          }
        }
      },
      "WorkerDocumentValidation": {
        "type": "object",
        "required": [
          "id",
          "company",
          "competency",
          "user",
          "validationType",
          "statusHistory",
          "createdAt",
          "updatedAt"
        ],
        "properties": {
          "id": {
            "type": "string",
            "nullable": true,
            "description": "Validation id",
            "example": "67bc36db80a1616ec3f48b01"
          },
          "company": {
            "$ref": "#/components/schemas/EntityReference"
          },
          "competency": {
            "$ref": "#/components/schemas/EntityReference"
          },
          "user": {
            "$ref": "#/components/schemas/UserReference"
          },
          "validationType": {
            "type": "string",
            "nullable": true,
            "description": "Validation source type",
            "enum": ["manual", "system"],
            "example": "manual"
          },
          "status": {
            "type": "string",
            "nullable": true,
            "description": "Validation status when present",
            "enum": ["validated", "referred", "invalid"],
            "example": "validated"
          },
          "invalidReason": {
            "type": "string",
            "description": "Invalidation reason code when status is invalid",
            "example": "expired"
          },
          "invalidReasonText": {
            "type": "string",
            "description": "Additional invalidation notes when provided",
            "example": "Card expired before assignment start"
          },
          "resolvedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Timestamp when the validation was resolved when present"
          },
          "documentType": {
            "type": "string",
            "nullable": true,
            "description": "Document type recorded on the validation row when present",
            "example": "attachment"
          },
          "documentRef": {
            "type": "string",
            "nullable": true,
            "description": "Candidate document id referenced by the validation when present",
            "example": "67bc36db80a1616ec3f48a10"
          },
          "statusHistory": {
            "type": "array",
            "description": "Validation status history entries",
            "items": {
              "$ref": "#/components/schemas/WorkerDocumentValidationStatusHistoryEntry"
            }
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Validation creation timestamp"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Validation update timestamp"
          }
        }
      },
      "WorkerDocument": {
        "type": "object",
        "required": [
          "id",
          "type",
          "documentType",
          "documentNumber",
          "indefinite",
          "createdAt",
          "files"
        ],
        "properties": {
          "id": {
            "type": "string",
            "nullable": true,
            "description": "Worker document id",
            "example": "67bc36db80a1616ec3f48a10"
          },
          "type": {
            "type": "string",
            "description": "Document collection on the worker record",
            "enum": ["attachment", "rightToWork"],
            "example": "attachment"
          },
          "documentType": {
            "type": "string",
            "description": "Document type label",
            "example": "CSCS Card"
          },
          "documentNumber": {
            "type": "string",
            "description": "Document number where available",
            "example": "CSCS-123"
          },
          "expiration": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Document expiration timestamp when present"
          },
          "indefinite": {
            "type": "boolean",
            "description": "Whether the document has no expiry date",
            "example": false
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Timestamp when the document was added"
          },
          "files": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WorkerDocumentFile"
            }
          },
          "verification": {
            "$ref": "#/components/schemas/WorkerDocumentVerification"
          },
          "systemValidation": {
            "$ref": "#/components/schemas/WorkerDocumentSystemValidation"
          },
          "validations": {
            "type": "array",
            "description": "Returned only when includeDocumentValidations=true. Non-system rows are limited to companies linked to the API key",
            "items": {
              "$ref": "#/components/schemas/WorkerDocumentValidation"
            }
          }
        }
      },
      "Worker": {
        "type": "object",
        "required": [
          "id",
          "reference",
          "firstName",
          "lastName",
          "name",
          "agencies",
          "trades",
          "attachments",
          "rightToWork",
          "createdAt",
          "updatedAt"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "Worker id",
            "example": "67bc36db80a1616ec3f48999"
          },
          "reference": {
            "type": "string",
            "description": "Worker reference",
            "example": "WK-1001"
          },
          "firstName": {
            "type": "string",
            "description": "Worker first name",
            "example": "Jordan"
          },
          "lastName": {
            "type": "string",
            "description": "Worker last name",
            "example": "Smith"
          },
          "name": {
            "type": "string",
            "description": "Worker full name",
            "example": "Jordan Smith"
          },
          "gender": {
            "type": "string",
            "nullable": true,
            "description": "Worker gender",
            "example": "male"
          },
          "nationalIns": {
            "type": "string",
            "nullable": true,
            "description": "National Insurance number",
            "example": "AB123456C"
          },
          "passportNo": {
            "type": "string",
            "nullable": true,
            "description": "Passport number",
            "example": "P1234567"
          },
          "nationality": {
            "type": "string",
            "nullable": true,
            "description": "Worker nationality",
            "example": "British"
          },
          "dob": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Date of birth"
          },
          "phone": {
            "$ref": "#/components/schemas/PhoneNumber"
          },
          "email": {
            "type": "string",
            "nullable": true,
            "description": "Worker email address",
            "example": "jordan@example.com"
          },
          "address": {
            "$ref": "#/components/schemas/Address"
          },
          "agencies": {
            "type": "array",
            "description": "Agency links for this worker",
            "items": {
              "$ref": "#/components/schemas/WorkerAgency"
            }
          },
          "trades": {
            "type": "array",
            "description": "Worker trades",
            "items": {
              "$ref": "#/components/schemas/EntityReference"
            }
          },
          "attachments": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WorkerDocument"
            }
          },
          "rightToWork": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WorkerDocument"
            }
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "description": "Worker creation timestamp"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time",
            "description": "Worker last update timestamp"
          }
        }
      },
      "WorkersListResponse": {
        "type": "object",
        "required": ["success", "data", "meta"],
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Worker"
            }
          },
          "meta": {
            "$ref": "#/components/schemas/PaginationMeta"
          }
        }
      },
      "WorkerResponse": {
        "type": "object",
        "required": ["success", "data"],
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "data": {
            "$ref": "#/components/schemas/Worker"
          }
        }
      }
    }
  },
  "security": [
    {
      "BearerApiKey": []
    }
  ],
  "x-webhooks": {
    "requisition_created": {
      "post": {
        "summary": "Requisition created event delivery",
        "description": "Sent when a new requisition is created. Payload includes only requisition id; fetch full details from GET /requisitions/{id}.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["id", "type", "createdAt", "data"],
                "properties": {
                  "id": {
                    "type": "string",
                    "example": "evt_01HYZ4KQJ4A9H2J7QZ8A4R7X9M"
                  },
                  "type": {
                    "type": "string",
                    "example": "requisition_created"
                  },
                  "createdAt": {
                    "type": "string",
                    "format": "date-time"
                  },
                  "data": {
                    "type": "object",
                    "required": ["requisition"],
                    "properties": {
                      "requisition": {
                        "type": "object",
                        "required": ["id"],
                        "properties": {
                          "id": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                }
              },
              "example": {
                "id": "evt_01HYZ4KQJ4A9H2J7QZ8A4R7X9M",
                "type": "requisition_created",
                "createdAt": "2026-02-24T15:05:43.455Z",
                "data": {
                  "requisition": {
                    "id": "req_01HYZ4JX2N2Q5F18J3Y41H8A2C"
                  }
                }
              }
            }
          }
        }
      }
    },
    "requisition_approved": {
      "post": {
        "summary": "Requisition approved event delivery",
        "description": "Sent whenever an approval stage is completed. Payload includes only requisition id; fetch full details from GET /requisitions/{id}.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["id", "type", "createdAt", "data"],
                "properties": {
                  "id": {
                    "type": "string",
                    "example": "evt_01HYZ4KXQ45Y8RD6MKJJ6RRA5S"
                  },
                  "type": {
                    "type": "string",
                    "example": "requisition_approved"
                  },
                  "createdAt": {
                    "type": "string",
                    "format": "date-time"
                  },
                  "data": {
                    "type": "object",
                    "required": ["requisition"],
                    "properties": {
                      "requisition": {
                        "type": "object",
                        "required": ["id"],
                        "properties": {
                          "id": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                }
              },
              "example": {
                "id": "evt_01HYZ4KXQ45Y8RD6MKJJ6RRA5S",
                "type": "requisition_approved",
                "createdAt": "2026-02-24T16:11:02.003Z",
                "data": {
                  "requisition": {
                    "id": "req_01HYZ4JX2N2Q5F18J3Y41H8A2C"
                  }
                }
              }
            }
          }
        }
      }
    },
    "assignment_confirmed": {
      "post": {
        "summary": "Assignment confirmed event delivery",
        "description": "Sent when an assignment is confirmed. Payload includes only assignment id; fetch full details from GET /assignments/{id}.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["id", "type", "createdAt", "data"],
                "properties": {
                  "id": {
                    "type": "string",
                    "example": "evt_01HZAZ8AA4H9P7T6QJ2W3K4M5N"
                  },
                  "type": {
                    "type": "string",
                    "example": "assignment_confirmed"
                  },
                  "createdAt": {
                    "type": "string",
                    "format": "date-time"
                  },
                  "data": {
                    "type": "object",
                    "required": ["assignment"],
                    "properties": {
                      "assignment": {
                        "type": "object",
                        "required": ["id"],
                        "properties": {
                          "id": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                }
              },
              "example": {
                "id": "evt_01HZAZ8AA4H9P7T6QJ2W3K4M5N",
                "type": "assignment_confirmed",
                "createdAt": "2026-03-09T10:15:00.000Z",
                "data": {
                  "assignment": {
                    "id": "asg01abcd2"
                  }
                }
              }
            }
          }
        }
      }
    },
    "timesheet_approved": {
      "post": {
        "summary": "Timesheet approved event delivery",
        "description": "Sent when a timesheet is approved. Payload includes only timesheet id.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["id", "type", "createdAt", "data"],
                "properties": {
                  "id": {
                    "type": "string",
                    "example": "evt_01HZAZ9BB5J1R8V7SK3X4L6P7Q"
                  },
                  "type": {
                    "type": "string",
                    "example": "timesheet_approved"
                  },
                  "createdAt": {
                    "type": "string",
                    "format": "date-time"
                  },
                  "data": {
                    "type": "object",
                    "required": ["timesheet"],
                    "properties": {
                      "timesheet": {
                        "type": "object",
                        "required": ["id"],
                        "properties": {
                          "id": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                }
              },
              "example": {
                "id": "evt_01HZAZ9BB5J1R8V7SK3X4L6P7Q",
                "type": "timesheet_approved",
                "createdAt": "2026-03-09T10:45:00.000Z",
                "data": {
                  "timesheet": {
                    "id": "ts01abcd34"
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "paths": {
    "/me": {
      "get": {
        "summary": "Get API key info",
        "description": "Returns information about the authenticated API key — name, description, scopes, configured per-minute and daily limits, current daily usage, IP allowlist, expiry, and linked companies. No additional scope is required beyond a valid API key.",
        "tags": ["Key"],
        "security": [
          {
            "BearerApiKey": []
          }
        ],
        "parameters": [],
        "responses": {
          "200": {
            "description": "API key information",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiKeyInfoResponse"
                }
              }
            }
          }
        }
      }
    },
    "/companies": {
      "get": {
        "summary": "List companies",
        "description": "Returns all companies linked to the API key, with optional filtering.",
        "tags": ["Companies"],
        "security": [
          {
            "BearerApiKey": ["read:companies"]
          }
        ],
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "Page number (default 1)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Records per page (default 50, max 200)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "Filter by company status",
            "schema": {
              "type": "string",
              "enum": ["active", "inactive"]
            }
          },
          {
            "name": "query",
            "in": "query",
            "required": false,
            "description": "Case-insensitive search against company name",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "description": "Created date filter start (YYYY-MM-DD)",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "description": "Created date filter end (YYYY-MM-DD)",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "sortBy",
            "in": "query",
            "required": false,
            "description": "Sort field (default name)",
            "schema": {
              "type": "string",
              "enum": ["createdAt", "updatedAt", "name"]
            }
          },
          {
            "name": "sortOrder",
            "in": "query",
            "required": false,
            "description": "Sort direction (default asc)",
            "schema": {
              "type": "string",
              "enum": ["asc", "desc"]
            }
          },
          {
            "name": "includeConfig",
            "in": "query",
            "required": false,
            "description": "If true, includes the company config object in each response row.",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Companies list",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CompaniesListResponse"
                }
              }
            }
          }
        }
      }
    },
    "/companies/{id}": {
      "get": {
        "summary": "Get company",
        "description": "Returns a single company by id.",
        "tags": ["Companies"],
        "security": [
          {
            "BearerApiKey": ["read:companies"]
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Company identifier",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "includeConfig",
            "in": "query",
            "required": false,
            "description": "If true, includes the company config object in the response.",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Company",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CompanyResponse"
                }
              }
            }
          }
        }
      }
    },
    "/companies/{id}/connected-agencies": {
      "get": {
        "summary": "List connected agencies",
        "description": "Returns company-level connected agencies for a single company.",
        "tags": ["Companies"],
        "security": [
          {
            "BearerApiKey": ["read:companies"]
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Company identifier",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "Page number (default 1)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Records per page (default 50, max 200)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          },
          {
            "name": "query",
            "in": "query",
            "required": false,
            "description": "Case-insensitive search against connected-agency name and email",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "description": "Created date filter start (YYYY-MM-DD)",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "description": "Created date filter end (YYYY-MM-DD)",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "sortBy",
            "in": "query",
            "required": false,
            "description": "Sort field (default name)",
            "schema": {
              "type": "string",
              "enum": ["createdAt", "updatedAt", "name", "tier"]
            }
          },
          {
            "name": "sortOrder",
            "in": "query",
            "required": false,
            "description": "Sort direction (default asc)",
            "schema": {
              "type": "string",
              "enum": ["asc", "desc"]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Connected agencies list",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConnectedAgenciesListResponse"
                }
              }
            }
          }
        }
      }
    },
    "/companies/{id}/competency-matrix": {
      "get": {
        "summary": "Get company's competency matrix",
        "description": "Returns all competency matrix entries for a single company. Requires the companies scope.",
        "tags": ["Companies"],
        "security": [
          {
            "BearerApiKey": ["read:companies"]
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Company identifier",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Company competency matrix",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CompanyCompetencyMatrixResponse"
                }
              }
            }
          }
        }
      }
    },
    "/regions": {
      "get": {
        "summary": "List regions",
        "description": "Returns regions for the companies linked to the API key.",
        "tags": ["Companies"],
        "security": [
          {
            "BearerApiKey": ["read:companies"]
          }
        ],
        "parameters": [
          {
            "name": "company",
            "in": "query",
            "required": false,
            "description": "Filter by company id. If omitted, regions for all linked companies are returned.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "Page number (default 1)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Records per page (default 50, max 200)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          },
          {
            "name": "sortBy",
            "in": "query",
            "required": false,
            "description": "Sort field (default name)",
            "schema": {
              "type": "string",
              "enum": ["createdAt", "updatedAt", "name"]
            }
          },
          {
            "name": "sortOrder",
            "in": "query",
            "required": false,
            "description": "Sort direction (default asc)",
            "schema": {
              "type": "string",
              "enum": ["asc", "desc"]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Regions list",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RegionsListResponse"
                }
              }
            }
          }
        }
      }
    },
    "/sectors": {
      "get": {
        "summary": "List sectors",
        "description": "Returns sectors for the companies linked to the API key.",
        "tags": ["Companies"],
        "security": [
          {
            "BearerApiKey": ["read:companies"]
          }
        ],
        "parameters": [
          {
            "name": "company",
            "in": "query",
            "required": false,
            "description": "Filter by company id. If omitted, sectors for all linked companies are returned.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "Page number (default 1)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Records per page (default 50, max 200)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          },
          {
            "name": "sortBy",
            "in": "query",
            "required": false,
            "description": "Sort field (default name)",
            "schema": {
              "type": "string",
              "enum": ["createdAt", "updatedAt", "name"]
            }
          },
          {
            "name": "sortOrder",
            "in": "query",
            "required": false,
            "description": "Sort direction (default asc)",
            "schema": {
              "type": "string",
              "enum": ["asc", "desc"]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Sectors list",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SectorsListResponse"
                }
              }
            }
          }
        }
      }
    },
    "/trades": {
      "get": {
        "summary": "List trades",
        "description": "Returns trades for the companies linked to the API key.",
        "tags": ["Trades"],
        "security": [
          {
            "BearerApiKey": ["read:trades"]
          }
        ],
        "parameters": [
          {
            "name": "company",
            "in": "query",
            "required": false,
            "description": "Filter by company id. If omitted, trades for all linked companies are returned.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "Page number (default 1)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Records per page (default 50, max 200)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "Filter by trade status",
            "schema": {
              "type": "string",
              "enum": ["active", "inactive"]
            }
          },
          {
            "name": "query",
            "in": "query",
            "required": false,
            "description": "Case-insensitive search against trade name",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "description": "Created date filter start (YYYY-MM-DD)",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "description": "Created date filter end (YYYY-MM-DD)",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "sortBy",
            "in": "query",
            "required": false,
            "description": "Sort field (default name)",
            "schema": {
              "type": "string",
              "enum": ["createdAt", "updatedAt", "name"]
            }
          },
          {
            "name": "sortOrder",
            "in": "query",
            "required": false,
            "description": "Sort direction (default asc)",
            "schema": {
              "type": "string",
              "enum": ["asc", "desc"]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Trades list",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TradesListResponse"
                }
              }
            }
          }
        }
      }
    },
    "/trades/{id}": {
      "get": {
        "summary": "Get trade",
        "description": "Returns a single trade by id or nanoid.",
        "tags": ["Trades"],
        "security": [
          {
            "BearerApiKey": ["read:trades"]
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Trade id or nanoid",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "includeRates",
            "in": "query",
            "required": false,
            "description": "If true, includes rate records for the trade.",
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "includeCompetencyMatrix",
            "in": "query",
            "required": false,
            "description": "If true, includes competency matrix entries for the trade.",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Trade",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TradeResponse"
                }
              }
            }
          }
        }
      }
    },
    "/rates": {
      "get": {
        "summary": "List rates",
        "description": "Returns rate records for the companies linked to the API key.",
        "tags": ["Rates"],
        "security": [
          {
            "BearerApiKey": ["read:rates"]
          }
        ],
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "Page number (default 1)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Records per page (default 50, max 200)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          },
          {
            "name": "company",
            "in": "query",
            "required": false,
            "description": "Filter by company id. If omitted, rates for all linked companies are returned.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "region",
            "in": "query",
            "required": false,
            "description": "Filter by region id",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "sector",
            "in": "query",
            "required": false,
            "description": "Filter by sector id",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "project",
            "in": "query",
            "required": false,
            "description": "Filter by project id",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "agency",
            "in": "query",
            "required": false,
            "description": "Filter by agency id",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "query",
            "in": "query",
            "required": false,
            "description": "Case-insensitive search against trade, region, sector, project, and agency names",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "description": "Created date filter start (YYYY-MM-DD)",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "description": "Created date filter end (YYYY-MM-DD)",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "sortBy",
            "in": "query",
            "required": false,
            "description": "Sort field (default tradeName)",
            "schema": {
              "type": "string",
              "enum": [
                "createdAt",
                "updatedAt",
                "tradeName",
                "regionName",
                "sectorName",
                "projectName",
                "supplierName"
              ]
            }
          },
          {
            "name": "sortOrder",
            "in": "query",
            "required": false,
            "description": "Sort direction (default asc)",
            "schema": {
              "type": "string",
              "enum": ["asc", "desc"]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Rates list",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RatesListResponse"
                }
              }
            }
          }
        }
      }
    },
    "/projects": {
      "get": {
        "summary": "List projects",
        "parameters": [
          {
            "name": "company",
            "in": "query",
            "required": false,
            "description": "Filter by company id. If omitted, data for all companies linked to the API key is returned.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "Page number (default 1)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Records per page (default 50, max 200)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "Filter by project status",
            "schema": {
              "type": "string",
              "enum": ["active", "inactive"]
            }
          },
          {
            "name": "region",
            "in": "query",
            "required": false,
            "description": "Filter by region id",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "sector",
            "in": "query",
            "required": false,
            "description": "Filter by sector id",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "query",
            "in": "query",
            "required": false,
            "description": "Case-insensitive search against project name and code",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "description": "Created date filter start (`YYYY-MM-DD`)",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "description": "Created date filter end (`YYYY-MM-DD`)",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "sortBy",
            "in": "query",
            "required": false,
            "description": "Sort field (default `name`)",
            "schema": {
              "type": "string",
              "enum": ["createdAt", "updatedAt", "name", "code"],
              "default": "name"
            }
          },
          {
            "name": "sortOrder",
            "in": "query",
            "required": false,
            "description": "Sort direction (default `asc`)",
            "schema": {
              "type": "string",
              "enum": ["asc", "desc"],
              "default": "asc"
            }
          },
          {
            "name": "includeConfig",
            "in": "query",
            "required": false,
            "description": "If true, includes the project config object in each response row.",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Projects returned successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProjectsListResponse"
                },
                "example": {
                  "success": true,
                  "data": [
                    {
                      "id": "67bc36db80a1616ec3f4739e",
                      "nanoid": "abc123def4",
                      "name": "Northern Rail Electrification",
                      "code": "NRE-001",
                      "email": "pm@requidex.com",
                      "phone": {
                        "countryCode": "+44",
                        "number": "1234567890"
                      },
                      "active": true,
                      "singleSite": false,
                      "siteCount": 3,
                      "company": {
                        "id": "67bc36db80a1616ec3f47001",
                        "name": "Requidex Construction Ltd"
                      },
                      "region": {
                        "id": "67bc36db80a1616ec3f47002",
                        "name": "North West"
                      },
                      "sector": {
                        "id": "67bc36db80a1616ec3f47003",
                        "name": "Rail"
                      },
                      "dates": {
                        "start": "2025-01-15T00:00:00.000Z",
                        "end": "2026-12-31T23:59:59.999Z"
                      },
                      "createdAt": "2025-01-10T12:00:00.000Z",
                      "updatedAt": "2026-02-20T14:03:12.111Z"
                    }
                  ],
                  "meta": {
                    "page": 1,
                    "limit": 50,
                    "total": 1
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, revoked, or expired API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden due to scope or IP restrictions",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "405": {
            "description": "Method not allowed on Open API routes",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected internal error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/projects/{id}": {
      "get": {
        "summary": "Get project",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Project identifier",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "includeConfig",
            "in": "query",
            "required": false,
            "description": "If true, includes the project config object in the response.",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Project returned successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProjectResponse"
                },
                "example": {
                  "success": true,
                  "data": {
                    "id": "67bc36db80a1616ec3f4739e",
                    "nanoid": "abc123def4",
                    "name": "Northern Rail Electrification",
                    "code": "NRE-001",
                    "email": "pm@requidex.com",
                    "phone": {
                      "countryCode": "+44",
                      "number": "1234567890"
                    },
                    "active": true,
                    "singleSite": false,
                    "siteCount": 3,
                    "company": {
                      "id": "67bc36db80a1616ec3f47001",
                      "name": "Requidex Construction Ltd"
                    },
                    "region": {
                      "id": "67bc36db80a1616ec3f47002",
                      "name": "North West"
                    },
                    "sector": {
                      "id": "67bc36db80a1616ec3f47003",
                      "name": "Rail"
                    },
                    "dates": {
                      "start": "2025-01-15T00:00:00.000Z",
                      "end": "2026-12-31T23:59:59.999Z"
                    },
                    "createdAt": "2025-01-10T12:00:00.000Z",
                    "updatedAt": "2026-02-20T14:03:12.111Z"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, revoked, or expired API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden due to scope or IP restrictions",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Project not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "405": {
            "description": "Method not allowed on Open API routes",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected internal error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/purchase-orders": {
      "get": {
        "summary": "List purchase orders",
        "description": "Returns purchase orders for the companies linked to the API key.",
        "tags": ["Purchase Orders"],
        "security": [
          {
            "BearerApiKey": ["read:purchase-orders"]
          }
        ],
        "parameters": [
          {
            "name": "company",
            "in": "query",
            "required": false,
            "description": "Filter by company id. If omitted, purchase orders for all linked companies are returned.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "Page number (default 1)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Records per page (default 50, max 200)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          },
          {
            "name": "project",
            "in": "query",
            "required": false,
            "description": "Filter by project id",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "site",
            "in": "query",
            "required": false,
            "description": "Filter by site id",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "agency",
            "in": "query",
            "required": false,
            "description": "Filter by agency id",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "Filter by purchase order status",
            "schema": {
              "type": "string",
              "enum": ["active", "inactive"]
            }
          },
          {
            "name": "query",
            "in": "query",
            "required": false,
            "description": "Case-insensitive search against purchase order reference",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "description": "Created date filter start (`YYYY-MM-DD`)",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "description": "Created date filter end (`YYYY-MM-DD`)",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "sortBy",
            "in": "query",
            "required": false,
            "description": "Sort field (default `createdAt`)",
            "schema": {
              "type": "string",
              "enum": ["createdAt", "updatedAt", "poRef", "start", "end", "value"],
              "default": "createdAt"
            }
          },
          {
            "name": "sortOrder",
            "in": "query",
            "required": false,
            "description": "Sort direction (default `desc`)",
            "schema": {
              "type": "string",
              "enum": ["asc", "desc"],
              "default": "desc"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Purchase orders returned successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PurchaseOrdersListResponse"
                }
              }
            }
          }
        }
      }
    },
    "/purchase-orders/{id}": {
      "get": {
        "summary": "Get purchase order",
        "description": "Returns a single purchase order by id.",
        "tags": ["Purchase Orders"],
        "security": [
          {
            "BearerApiKey": ["read:purchase-orders"]
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Purchase order identifier",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Purchase order returned successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PurchaseOrderResponse"
                }
              }
            }
          }
        }
      }
    },
    "/projects/{id}/connected-agencies": {
      "get": {
        "summary": "List connected agencies",
        "description": "Returns project-connected agencies, combining project-level agencies with company-level agencies that are not excluded from the project.",
        "tags": ["Projects"],
        "security": [
          {
            "BearerApiKey": ["read:projects"]
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Project identifier",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "Page number (default 1)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Records per page (default 50, max 200)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          },
          {
            "name": "query",
            "in": "query",
            "required": false,
            "description": "Case-insensitive search against connected-agency name and email",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "description": "Created date filter start (YYYY-MM-DD)",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "description": "Created date filter end (YYYY-MM-DD)",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "sortBy",
            "in": "query",
            "required": false,
            "description": "Sort field (default name)",
            "schema": {
              "type": "string",
              "enum": ["createdAt", "updatedAt", "name", "tier"]
            }
          },
          {
            "name": "sortOrder",
            "in": "query",
            "required": false,
            "description": "Sort direction (default asc)",
            "schema": {
              "type": "string",
              "enum": ["asc", "desc"]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Connected agencies list",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConnectedAgenciesListResponse"
                }
              }
            }
          }
        }
      }
    },
    "/sites": {
      "get": {
        "summary": "List sites",
        "parameters": [
          {
            "name": "company",
            "in": "query",
            "required": false,
            "description": "Filter by company id. If omitted, data for all companies linked to the API key is returned.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "Page number (default 1)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Records per page (default 50, max 200)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "Filter by site status",
            "schema": {
              "type": "string",
              "enum": ["active", "inactive"]
            }
          },
          {
            "name": "project",
            "in": "query",
            "required": false,
            "description": "Filter by project id",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "query",
            "in": "query",
            "required": false,
            "description": "Case-insensitive search against site name",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "description": "Created date filter start (`YYYY-MM-DD`)",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "description": "Created date filter end (`YYYY-MM-DD`)",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "sortBy",
            "in": "query",
            "required": false,
            "description": "Sort field (default `name`)",
            "schema": {
              "type": "string",
              "enum": ["createdAt", "updatedAt", "name"],
              "default": "name"
            }
          },
          {
            "name": "sortOrder",
            "in": "query",
            "required": false,
            "description": "Sort direction (default `asc`)",
            "schema": {
              "type": "string",
              "enum": ["asc", "desc"],
              "default": "asc"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Sites returned successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SitesListResponse"
                },
                "example": {
                  "success": true,
                  "data": [
                    {
                      "id": "67bc36db80a1616ec3f47055",
                      "nanoid": "site12abcd",
                      "name": "Manchester Central",
                      "project": {
                        "id": "67bc36db80a1616ec3f47011",
                        "name": "Northern Rail Electrification"
                      },
                      "company": {
                        "id": "67bc36db80a1616ec3f47001",
                        "name": "Requidex Construction Ltd"
                      },
                      "active": true,
                      "email": "site.manager@requidex.com",
                      "phone": {
                        "countryCode": "+44",
                        "number": "1234567891"
                      },
                      "address": {
                        "line1": "1 Station Approach",
                        "city": "Manchester",
                        "postcode": "M1 1AA"
                      },
                      "createdAt": "2025-02-01T09:00:00.000Z",
                      "updatedAt": "2026-02-20T14:03:12.111Z"
                    }
                  ],
                  "meta": {
                    "page": 1,
                    "limit": 50,
                    "total": 1
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, revoked, or expired API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden due to scope or IP restrictions",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "405": {
            "description": "Method not allowed on Open API routes",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected internal error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/sites/{id}": {
      "get": {
        "summary": "Get site",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Site identifier",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Site returned successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SiteResponse"
                },
                "example": {
                  "success": true,
                  "data": {
                    "id": "67bc36db80a1616ec3f47055",
                    "nanoid": "site12abcd",
                    "name": "Manchester Central",
                    "project": {
                      "id": "67bc36db80a1616ec3f47011",
                      "name": "Northern Rail Electrification"
                    },
                    "company": {
                      "id": "67bc36db80a1616ec3f47001",
                      "name": "Requidex Construction Ltd"
                    },
                    "active": true,
                    "email": "site.manager@requidex.com",
                    "phone": {
                      "countryCode": "+44",
                      "number": "1234567891"
                    },
                    "address": {
                      "line1": "1 Station Approach",
                      "city": "Manchester",
                      "postcode": "M1 1AA"
                    },
                    "createdAt": "2025-02-01T09:00:00.000Z",
                    "updatedAt": "2026-02-20T14:03:12.111Z"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, revoked, or expired API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden due to scope or IP restrictions",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Site not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "405": {
            "description": "Method not allowed on Open API routes",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected internal error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/requisitions": {
      "get": {
        "summary": "List requisitions",
        "parameters": [
          {
            "name": "company",
            "in": "query",
            "required": false,
            "description": "Filter by company id. If omitted, data for all companies linked to the API key is returned.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "Page number (default 1)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Records per page (default 50, max 200)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "Filter by derived requisition status",
            "schema": {
              "type": "string",
              "enum": ["raised", "approved", "filled", "cancelled", "rejected"]
            }
          },
          {
            "name": "project",
            "in": "query",
            "required": false,
            "description": "Filter by project id",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "site",
            "in": "query",
            "required": false,
            "description": "Filter by site id",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "costCode",
            "in": "query",
            "required": false,
            "description": "Filter by cost code id",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "trade",
            "in": "query",
            "required": false,
            "description": "Filter by trade id",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "agency",
            "in": "query",
            "required": false,
            "description": "Filter by agency id",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "query",
            "in": "query",
            "required": false,
            "description": "Case-insensitive search against requisition reference",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "description": "Created date filter start (`YYYY-MM-DD`)",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "description": "Created date filter end (`YYYY-MM-DD`)",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "sortBy",
            "in": "query",
            "required": false,
            "description": "Sort field",
            "schema": {
              "type": "string",
              "enum": ["createdAt", "updatedAt", "reqRef", "approvedDate"]
            }
          },
          {
            "name": "sortOrder",
            "in": "query",
            "required": false,
            "description": "Sort direction",
            "schema": {
              "type": "string",
              "enum": ["asc", "desc"]
            }
          },
          {
            "name": "includeTimelogs",
            "in": "query",
            "required": false,
            "description": "If true, includes timelog rows for each timesheet.",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Requisitions returned successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RequisitionsListResponse"
                },
                "example": {
                  "success": true,
                  "data": [
                    {
                      "id": "67bc36db80a1616ec3f48123",
                      "nanoid": "req01abcde",
                      "reference": "REQ-R1002",
                      "status": "raised",
                      "quantity": 4,
                      "company": {
                        "id": "67bc36db80a1616ec3f47001",
                        "name": "Requidex Construction Ltd"
                      },
                      "project": {
                        "id": "67bc36db80a1616ec3f47011",
                        "name": "Northern Rail Electrification"
                      },
                      "site": {
                        "id": "67bc36db80a1616ec3f47055",
                        "name": "Manchester Central"
                      },
                      "trade": {
                        "id": "67bc36db80a1616ec3f47077",
                        "name": "Electrician"
                      },
                      "activity": {
                        "id": "67bc36db80a1616ec3f47099",
                        "name": "Install containment"
                      },
                      "startDate": "2026-03-01T00:00:00.000Z",
                      "endDate": "2026-03-31T23:59:59.999Z",
                      "approvedDate": null,
                      "createdAt": "2026-02-20T11:10:00.000Z",
                      "updatedAt": "2026-02-20T11:10:00.000Z"
                    }
                  ],
                  "meta": {
                    "page": 1,
                    "limit": 50,
                    "total": 1
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, revoked, or expired API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden due to scope or IP restrictions",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "405": {
            "description": "Method not allowed on Open API routes",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected internal error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/requisitions/{id}": {
      "get": {
        "summary": "Get requisition",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Requisition identifier",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Requisition returned successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RequisitionResponse"
                },
                "example": {
                  "success": true,
                  "data": {
                    "id": "67bc36db80a1616ec3f48123",
                    "nanoid": "req01abcde",
                    "reference": "REQ-R1002",
                    "status": "raised",
                    "quantity": 4,
                    "company": {
                      "id": "67bc36db80a1616ec3f47001",
                      "name": "Requidex Construction Ltd"
                    },
                    "project": {
                      "id": "67bc36db80a1616ec3f47011",
                      "name": "Northern Rail Electrification"
                    },
                    "region": {
                      "id": "67bc36db80a1616ec3f47002",
                      "name": "North West"
                    },
                    "sector": {
                      "id": "67bc36db80a1616ec3f47003",
                      "name": "Rail"
                    },
                    "site": {
                      "id": "67bc36db80a1616ec3f47055",
                      "name": "Manchester Central"
                    },
                    "trade": {
                      "id": "67bc36db80a1616ec3f47077",
                      "name": "Electrician"
                    },
                    "activity": {
                      "id": "67bc36db80a1616ec3f47099",
                      "name": "Install containment"
                    },
                    "startDate": "2026-03-01T00:00:00.000Z",
                    "endDate": "2026-03-31T23:59:59.999Z",
                    "approvedDate": null,
                    "createdAt": "2026-02-20T11:10:00.000Z",
                    "updatedAt": "2026-02-20T11:10:00.000Z"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, revoked, or expired API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden due to scope or IP restrictions",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Requisition not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "405": {
            "description": "Method not allowed on Open API routes",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected internal error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/assignments": {
      "get": {
        "summary": "List assignments",
        "parameters": [
          {
            "name": "company",
            "in": "query",
            "required": false,
            "description": "Filter by company id. If omitted, data for all companies linked to the API key is returned.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "Page number (default 1)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Records per page (default 50, max 200)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "Filter by assignment status",
            "schema": {
              "type": "string",
              "enum": ["pending", "confirmed", "cancelled", "completed", "ended"]
            }
          },
          {
            "name": "project",
            "in": "query",
            "required": false,
            "description": "Filter by project id",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "site",
            "in": "query",
            "required": false,
            "description": "Filter by site id",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "trade",
            "in": "query",
            "required": false,
            "description": "Filter by trade id",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "worker",
            "in": "query",
            "required": false,
            "description": "Filter by worker id",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "agency",
            "in": "query",
            "required": false,
            "description": "Filter by agency id",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "requisition",
            "in": "query",
            "required": false,
            "description": "Filter by requisition id",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "query",
            "in": "query",
            "required": false,
            "description": "Case-insensitive search against assignment reference, worker name/reference, and agency name",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "description": "Created date filter start (`YYYY-MM-DD`)",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "description": "Created date filter end (`YYYY-MM-DD`)",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "sortBy",
            "in": "query",
            "required": false,
            "description": "Sort field",
            "schema": {
              "type": "string",
              "enum": ["createdAt", "updatedAt", "assignmentRef", "startDate", "endDate"]
            }
          },
          {
            "name": "sortOrder",
            "in": "query",
            "required": false,
            "description": "Sort direction",
            "schema": {
              "type": "string",
              "enum": ["asc", "desc"]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Assignments returned successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AssignmentsListResponse"
                },
                "example": {
                  "success": true,
                  "data": [
                    {
                      "id": "67bc36db80a1616ec3f49001",
                      "nanoid": "asg01abcd2",
                      "reference": "A1044",
                      "status": "confirmed",
                      "payType": "hourly",
                      "rateType": "cis",
                      "confirmationDate": "2026-02-24T09:00:00.000Z",
                      "cancellation": null,
                      "company": {
                        "id": "67bc36db80a1616ec3f47001",
                        "name": "Requidex Construction Ltd"
                      },
                      "project": {
                        "id": "67bc36db80a1616ec3f47011",
                        "name": "Northern Rail Electrification"
                      },
                      "region": {
                        "id": "67bc36db80a1616ec3f47002",
                        "name": "North West"
                      },
                      "sector": {
                        "id": "67bc36db80a1616ec3f47003",
                        "name": "Rail"
                      },
                      "site": {
                        "id": "67bc36db80a1616ec3f47055",
                        "name": "Manchester Central"
                      },
                      "trade": {
                        "id": "67bc36db80a1616ec3f47077",
                        "name": "Electrician"
                      },
                      "agency": {
                        "id": "67bc36db80a1616ec3f47101",
                        "name": "Northline Labour Desk"
                      },
                      "umbrella": "UmbrellaCo",
                      "worker": {
                        "id": "67bc36db80a1616ec3f48999",
                        "name": "Jordan Smith"
                      },
                      "workerDistanceToSite": 12.4,
                      "workerLodgeDistanceToSite": 4.8,
                      "requisition": {
                        "id": "67bc36db80a1616ec3f48123",
                        "reference": "REQ-R1002",
                        "nanoid": "req01abcde"
                      },
                      "costCode": {
                        "name": "CC-001",
                        "description": "Trackside installation"
                      },
                      "workActivity": "Install containment",
                      "rates": {
                        "pay": 21.5,
                        "charge": 28.75
                      },
                      "values": {
                        "pay": 3440,
                        "charge": 4600
                      },
                      "rateUplifts": {
                        "bh": 100,
                        "bhNw": 125,
                        "wdOt": 50,
                        "sat": 50,
                        "sun": 100,
                        "wdNw": 25,
                        "weNw": 40
                      },
                      "enhancedUplifts": {
                        "enabled": true,
                        "breakdown": [
                          {
                            "date": "2026-03-03T00:00:00.000Z",
                            "dayOfWeek": "Tuesday",
                            "shiftType": "dayShift",
                            "blockStartHour": 8,
                            "blockEndHour": 12,
                            "blockHours": 4,
                            "upliftPercentage": 25,
                            "chargeRate": 35.94,
                            "chargeValue": 143.76,
                            "payRate": 26.88,
                            "payValue": 107.52
                          }
                        ]
                      },
                      "lodgeApplicable": true,
                      "weeksElapsed": 6,
                      "purchaseOrder": "PO-44321",
                      "sds": null,
                      "sdc": {
                        "status": "confirmed",
                        "attachment": "https://files.requidex.com/sdc-confirmation.pdf"
                      },
                      "kid": "https://files.requidex.com/kid.pdf",
                      "startDate": "2026-03-01T00:00:00.000Z",
                      "endDate": "2026-03-31T23:59:59.999Z",
                      "timesheetStartDate": "2026-03-03T00:00:00.000Z",
                      "completedDate": null,
                      "createdAt": "2026-02-20T11:30:00.000Z",
                      "updatedAt": "2026-02-21T09:15:00.000Z"
                    }
                  ],
                  "meta": {
                    "page": 1,
                    "limit": 50,
                    "total": 1
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, revoked, or expired API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden due to scope or IP restrictions",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "405": {
            "description": "Method not allowed on Open API routes",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected internal error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/assignments/{id}": {
      "get": {
        "summary": "Get assignment",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Assignment identifier",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Assignment returned successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AssignmentResponse"
                },
                "example": {
                  "success": true,
                  "data": {
                    "id": "67bc36db80a1616ec3f49001",
                    "nanoid": "asg01abcd2",
                    "reference": "A1044",
                    "status": "confirmed",
                    "payType": "hourly",
                    "rateType": "cis",
                    "confirmationDate": "2026-02-24T09:00:00.000Z",
                    "cancellation": null,
                    "company": {
                      "id": "67bc36db80a1616ec3f47001",
                      "name": "Requidex Construction Ltd"
                    },
                    "project": {
                      "id": "67bc36db80a1616ec3f47011",
                      "name": "Northern Rail Electrification"
                    },
                    "region": {
                      "id": "67bc36db80a1616ec3f47002",
                      "name": "North West"
                    },
                    "sector": {
                      "id": "67bc36db80a1616ec3f47003",
                      "name": "Rail"
                    },
                    "site": {
                      "id": "67bc36db80a1616ec3f47055",
                      "name": "Manchester Central"
                    },
                    "trade": {
                      "id": "67bc36db80a1616ec3f47077",
                      "name": "Electrician"
                    },
                    "agency": {
                      "id": "67bc36db80a1616ec3f47101",
                      "name": "Northline Labour Desk"
                    },
                    "umbrella": "UmbrellaCo",
                    "worker": {
                      "id": "67bc36db80a1616ec3f48999",
                      "name": "Jordan Smith",
                      "reference": "WK-1044"
                    },
                    "workerDistanceToSite": 12.4,
                    "workerLodgeDistanceToSite": 4.8,
                    "requisition": {
                      "id": "67bc36db80a1616ec3f48123",
                      "reference": "REQ-R1002",
                      "nanoid": "req01abcde"
                    },
                    "costCode": {
                      "name": "CC-001",
                      "description": "Trackside installation"
                    },
                    "workActivity": "Install containment",
                    "rates": {
                      "pay": 21.5,
                      "charge": 28.75
                    },
                    "values": {
                      "pay": 3440,
                      "charge": 4600
                    },
                    "rateUplifts": {
                      "bh": 100,
                      "bhNw": 125,
                      "wdOt": 50,
                      "sat": 50,
                      "sun": 100,
                      "wdNw": 25,
                      "weNw": 40
                    },
                    "enhancedUplifts": {
                      "enabled": true,
                      "breakdown": [
                        {
                          "date": "2026-03-03T00:00:00.000Z",
                          "dayOfWeek": "Tuesday",
                          "shiftType": "dayShift",
                          "blockStartHour": 8,
                          "blockEndHour": 12,
                          "blockHours": 4,
                          "upliftPercentage": 25,
                          "chargeRate": 35.94,
                          "chargeValue": 143.76,
                          "payRate": 26.88,
                          "payValue": 107.52
                        }
                      ]
                    },
                    "lodgeApplicable": true,
                    "weeksElapsed": 6,
                    "purchaseOrder": "PO-44321",
                    "sds": null,
                    "sdc": {
                      "status": "confirmed",
                      "attachment": "https://files.requidex.com/sdc-confirmation.pdf"
                    },
                    "kid": "https://files.requidex.com/kid.pdf",
                    "startDate": "2026-03-01T00:00:00.000Z",
                    "endDate": "2026-03-31T23:59:59.999Z",
                    "timesheetStartDate": "2026-03-03T00:00:00.000Z",
                    "completedDate": null,
                    "createdAt": "2026-02-20T11:30:00.000Z",
                    "updatedAt": "2026-02-21T09:15:00.000Z"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, revoked, or expired API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden due to scope or IP restrictions",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Assignment not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "405": {
            "description": "Method not allowed on Open API routes",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected internal error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/timesheets": {
      "get": {
        "summary": "List timesheets",
        "tags": ["Timesheets"],
        "security": [
          {
            "BearerApiKey": ["read:timesheets"]
          }
        ],
        "parameters": [
          {
            "name": "company",
            "in": "query",
            "required": false,
            "description": "Filter by company id. If omitted, data for all companies linked to the API key is returned.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "Page number (default 1)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Records per page (default 50, max 200)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "Filter by timesheet status",
            "schema": {
              "type": "string",
              "enum": ["pending", "pending_approval", "approved", "cancelled", "absent"]
            }
          },
          {
            "name": "project",
            "in": "query",
            "required": false,
            "description": "Filter by project id",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "site",
            "in": "query",
            "required": false,
            "description": "Filter by site id",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "assignment",
            "in": "query",
            "required": false,
            "description": "Filter by assignment id",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "worker",
            "in": "query",
            "required": false,
            "description": "Filter by worker id",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "agency",
            "in": "query",
            "required": false,
            "description": "Filter by agency id",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "query",
            "in": "query",
            "required": false,
            "description": "Case-insensitive search against timesheet reference, worker name/reference, and agency name",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "description": "Created date filter start (`YYYY-MM-DD`)",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "description": "Created date filter end (`YYYY-MM-DD`)",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "sortBy",
            "in": "query",
            "required": false,
            "description": "Sort field",
            "schema": {
              "type": "string",
              "enum": ["createdAt", "updatedAt", "timesheetRef", "start", "we", "approvedDate"]
            }
          },
          {
            "name": "sortOrder",
            "in": "query",
            "required": false,
            "description": "Sort direction",
            "schema": {
              "type": "string",
              "enum": ["asc", "desc"]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Timesheets returned successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TimesheetsListResponse"
                },
                "example": {
                  "success": true,
                  "data": [
                    {
                      "id": "67bc36db80a1616ec3f4a001",
                      "reference": "TS-1044",
                      "status": "approved",
                      "worker": {
                        "id": "67bc36db80a1616ec3f48999",
                        "name": "Jordan Smith"
                      },
                      "assignment": {
                        "id": "67bc36db80a1616ec3f49001",
                        "reference": "A1044"
                      },
                      "company": {
                        "id": "67bc36db80a1616ec3f47001",
                        "name": "Requidex Construction Ltd"
                      },
                      "project": {
                        "id": "67bc36db80a1616ec3f47011",
                        "name": "Northern Rail Electrification"
                      },
                      "site": {
                        "id": "67bc36db80a1616ec3f47055",
                        "name": "Manchester Central"
                      },
                      "agency": {
                        "id": "67bc36db80a1616ec3f47101",
                        "name": "Northline Labour Desk"
                      },
                      "payType": "hourly",
                      "rateType": "cis",
                      "start": "2026-03-02T00:00:00.000Z",
                      "end": "2026-03-08T23:59:59.999Z",
                      "weekEnding": "2026-03-08T00:00:00.000Z",
                      "version": 2,
                      "approvedDate": "2026-03-09T09:15:00.000Z",
                      "netHours": 37.5,
                      "rates": {
                        "wd": {
                          "pay": 21.5,
                          "emp": 2.93,
                          "margin": 4.32,
                          "charge": 28.75,
                          "uplift": null
                        },
                        "wdNw": {
                          "pay": 0,
                          "emp": 0,
                          "margin": 0,
                          "charge": 0,
                          "uplift": 25
                        },
                        "weNw": {
                          "pay": 0,
                          "emp": 0,
                          "margin": 0,
                          "charge": 0,
                          "uplift": 40
                        },
                        "bh": {
                          "pay": 0,
                          "emp": 0,
                          "margin": 0,
                          "charge": 0,
                          "uplift": 100
                        },
                        "bhNight": {
                          "pay": 0,
                          "emp": 0,
                          "margin": 0,
                          "charge": 0,
                          "uplift": 125
                        },
                        "sat": {
                          "pay": 32.25,
                          "emp": 4.39,
                          "margin": 6.48,
                          "charge": 43.13,
                          "uplift": 50
                        },
                        "sun": {
                          "pay": 43,
                          "emp": 5.86,
                          "margin": 8.64,
                          "charge": 57.5,
                          "uplift": 100
                        },
                        "ot": {
                          "pay": 32.25,
                          "emp": 4.39,
                          "margin": 6.48,
                          "charge": 43.13,
                          "uplift": 50
                        }
                      },
                      "values": {
                        "pay": {
                          "wdBasic": 860,
                          "wdOvertime": 215,
                          "wdNightwork": 0,
                          "weNightwork": 0,
                          "bankHoliday": 0,
                          "bankHolidayNight": 0,
                          "saturday": 294,
                          "sunday": 295,
                          "saturdayNightwork": 0,
                          "sundayNightwork": 0,
                          "total": 1664
                        },
                        "charge": {
                          "wdBasic": 1150,
                          "wdOvertime": 287.5,
                          "wdNightwork": 0,
                          "weNightwork": 0,
                          "bankHoliday": 0,
                          "bankHolidayNight": 0,
                          "saturday": 396,
                          "sunday": 396.5,
                          "saturdayNightwork": 0,
                          "sundayNightwork": 0,
                          "total": 2230
                        },
                        "expense": 125
                      },
                      "createdAt": "2026-03-08T18:00:00.000Z",
                      "updatedAt": "2026-03-09T09:15:00.000Z"
                    }
                  ],
                  "meta": {
                    "page": 1,
                    "limit": 50,
                    "total": 1
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, revoked, or expired API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden due to scope or IP restrictions",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "405": {
            "description": "Method not allowed on Open API routes",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected internal error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/timesheets/{id}": {
      "get": {
        "summary": "Get timesheet",
        "tags": ["Timesheets"],
        "security": [
          {
            "BearerApiKey": ["read:timesheets"]
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Timesheet identifier",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "includeVersionHistory",
            "in": "query",
            "required": false,
            "description": "If true, includes version history snapshots for the timesheet.",
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "includeTimelogs",
            "in": "query",
            "required": false,
            "description": "If true, includes timelog rows for the timesheet.",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Timesheet returned successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TimesheetResponse"
                },
                "example": {
                  "success": true,
                  "data": {
                    "id": "67bc36db80a1616ec3f4a001",
                    "reference": "TS-1044",
                    "status": "approved",
                    "worker": {
                      "id": "67bc36db80a1616ec3f48999",
                      "name": "Jordan Smith"
                    },
                    "assignment": {
                      "id": "67bc36db80a1616ec3f49001",
                      "reference": "A1044"
                    },
                    "company": {
                      "id": "67bc36db80a1616ec3f47001",
                      "name": "Requidex Construction Ltd"
                    },
                    "project": {
                      "id": "67bc36db80a1616ec3f47011",
                      "name": "Northern Rail Electrification"
                    },
                    "site": {
                      "id": "67bc36db80a1616ec3f47055",
                      "name": "Manchester Central"
                    },
                    "agency": {
                      "id": "67bc36db80a1616ec3f47101",
                      "name": "Northline Labour Desk"
                    },
                    "payType": "hourly",
                    "rateType": "cis",
                    "start": "2026-03-02T00:00:00.000Z",
                    "end": "2026-03-08T23:59:59.999Z",
                    "weekEnding": "2026-03-08T00:00:00.000Z",
                    "version": 2,
                    "approvedDate": "2026-03-09T09:15:00.000Z",
                    "netHours": 37.5,
                    "rates": {
                      "wd": {
                        "pay": 21.5,
                        "emp": 2.93,
                        "margin": 4.32,
                        "charge": 28.75,
                        "uplift": null
                      },
                      "wdNw": {
                        "pay": 0,
                        "emp": 0,
                        "margin": 0,
                        "charge": 0,
                        "uplift": 25
                      },
                      "weNw": {
                        "pay": 0,
                        "emp": 0,
                        "margin": 0,
                        "charge": 0,
                        "uplift": 40
                      },
                      "bh": {
                        "pay": 0,
                        "emp": 0,
                        "margin": 0,
                        "charge": 0,
                        "uplift": 100
                      },
                      "bhNight": {
                        "pay": 0,
                        "emp": 0,
                        "margin": 0,
                        "charge": 0,
                        "uplift": 125
                      },
                      "sat": {
                        "pay": 32.25,
                        "emp": 4.39,
                        "margin": 6.48,
                        "charge": 43.13,
                        "uplift": 50
                      },
                      "sun": {
                        "pay": 43,
                        "emp": 5.86,
                        "margin": 8.64,
                        "charge": 57.5,
                        "uplift": 100
                      },
                      "ot": {
                        "pay": 32.25,
                        "emp": 4.39,
                        "margin": 6.48,
                        "charge": 43.13,
                        "uplift": 50
                      }
                    },
                    "values": {
                      "pay": {
                        "wdBasic": 860,
                        "wdOvertime": 215,
                        "wdNightwork": 0,
                        "weNightwork": 0,
                        "bankHoliday": 0,
                        "bankHolidayNight": 0,
                        "saturday": 294,
                        "sunday": 295,
                        "saturdayNightwork": 0,
                        "sundayNightwork": 0,
                        "total": 1664
                      },
                      "charge": {
                        "wdBasic": 1150,
                        "wdOvertime": 287.5,
                        "wdNightwork": 0,
                        "weNightwork": 0,
                        "bankHoliday": 0,
                        "bankHolidayNight": 0,
                        "saturday": 396,
                        "sunday": 396.5,
                        "saturdayNightwork": 0,
                        "sundayNightwork": 0,
                        "total": 2230
                      },
                      "expense": 125
                    },
                    "timelogs": [
                      {
                        "id": "67bc36db80a1616ec3f4a101",
                        "status": "approved",
                        "date": "2026-03-03T00:00:00.000Z",
                        "start": "2026-03-03T08:00:00.000Z",
                        "end": "2026-03-03T17:00:00.000Z",
                        "shiftType": "day",
                        "breaks": 30,
                        "rateDescription": "wdBasic",
                        "hours": {
                          "standard": 8,
                          "overtime": 0,
                          "total": 8
                        },
                        "rates": {
                          "pay": 21.5,
                          "emp": 2.93,
                          "margin": 4.32,
                          "charge": 28.75
                        },
                        "values": {
                          "pay": {
                            "standard": 172,
                            "overtime": 0,
                            "total": 172
                          },
                          "emp": {
                            "standard": 23.44,
                            "overtime": 0,
                            "total": 23.44
                          },
                          "margin": {
                            "standard": 34.56,
                            "overtime": 0,
                            "total": 34.56
                          },
                          "charge": {
                            "standard": 230,
                            "overtime": 0,
                            "total": 230
                          }
                        },
                        "absenceAuthorized": null,
                        "absenceReason": null,
                        "costCodeAllocations": [
                          {
                            "costCode": {
                              "name": "CC-001",
                              "description": "Trackside installation"
                            },
                            "hours": 8
                          }
                        ]
                      }
                    ],
                    "versionHistory": [
                      {
                        "version": 1,
                        "snapshotReason": "created",
                        "snapshotAt": "2026-03-08T18:00:00.000Z",
                        "netHours": 37.5,
                        "expenseValue": 0,
                        "values": {
                          "pay": {
                            "wdBasic": 860,
                            "wdOvertime": 215,
                            "wdNightwork": 0,
                            "weNightwork": 0,
                            "bankHoliday": 0,
                            "bankHolidayNight": 0,
                            "saturday": 294,
                            "sunday": 295,
                            "saturdayNightwork": 0,
                            "sundayNightwork": 0,
                            "total": 1664
                          },
                          "charge": {
                            "wdBasic": 1150,
                            "wdOvertime": 287.5,
                            "wdNightwork": 0,
                            "weNightwork": 0,
                            "bankHoliday": 0,
                            "bankHolidayNight": 0,
                            "saturday": 396,
                            "sunday": 396.5,
                            "saturdayNightwork": 0,
                            "sundayNightwork": 0,
                            "total": 2230
                          },
                          "expense": 0
                        },
                        "rates": {
                          "wd": {
                            "pay": 21.5,
                            "emp": 2.93,
                            "margin": 4.32,
                            "charge": 28.75,
                            "uplift": null
                          },
                          "wdNw": {
                            "pay": 0,
                            "emp": 0,
                            "margin": 0,
                            "charge": 0,
                            "uplift": 25
                          },
                          "weNw": {
                            "pay": 0,
                            "emp": 0,
                            "margin": 0,
                            "charge": 0,
                            "uplift": 40
                          },
                          "bh": {
                            "pay": 0,
                            "emp": 0,
                            "margin": 0,
                            "charge": 0,
                            "uplift": 100
                          },
                          "bhNight": {
                            "pay": 0,
                            "emp": 0,
                            "margin": 0,
                            "charge": 0,
                            "uplift": 125
                          },
                          "sat": {
                            "pay": 32.25,
                            "emp": 4.39,
                            "margin": 6.48,
                            "charge": 43.13,
                            "uplift": 50
                          },
                          "sun": {
                            "pay": 43,
                            "emp": 5.86,
                            "margin": 8.64,
                            "charge": 57.5,
                            "uplift": 100
                          },
                          "ot": {
                            "pay": 32.25,
                            "emp": 4.39,
                            "margin": 6.48,
                            "charge": 43.13,
                            "uplift": 50
                          }
                        }
                      }
                    ],
                    "createdAt": "2026-03-08T18:00:00.000Z",
                    "updatedAt": "2026-03-09T09:15:00.000Z"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, revoked, or expired API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden due to scope or IP restrictions",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Timesheet not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "405": {
            "description": "Method not allowed on Open API routes",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected internal error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/credit-notes": {
      "get": {
        "summary": "List credit notes",
        "tags": ["Credit Notes"],
        "security": [
          {
            "BearerApiKey": ["read:credit-notes"]
          }
        ],
        "parameters": [
          {
            "name": "company",
            "in": "query",
            "required": false,
            "description": "Filter by company id. If omitted, data for all companies linked to the API key is returned.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "Page number (default 1)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Records per page (default 50, max 200)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "Filter by credit note status",
            "schema": {
              "type": "string",
              "enum": ["pending", "processed"]
            }
          },
          {
            "name": "project",
            "in": "query",
            "required": false,
            "description": "Filter by project id",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "agency",
            "in": "query",
            "required": false,
            "description": "Filter by agency id",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "invoiceType",
            "in": "query",
            "required": false,
            "description": "Filter by credit note flow type",
            "schema": {
              "type": "string",
              "enum": ["supplierToClient", "supplierToMsp", "mspToClient"]
            }
          },
          {
            "name": "mspInvoiceType",
            "in": "query",
            "required": false,
            "description": "Filter by MSP credit note subtype",
            "schema": {
              "type": "string",
              "enum": ["receivable", "payable"]
            }
          },
          {
            "name": "query",
            "in": "query",
            "required": false,
            "description": "Case-insensitive search against credit note reference, reason, comments, and contextual supplier/MSP names",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "description": "Created date filter start (`YYYY-MM-DD`)",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "description": "Created date filter end (`YYYY-MM-DD`)",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "sortBy",
            "in": "query",
            "required": false,
            "description": "Sort field",
            "schema": {
              "type": "string",
              "enum": ["createdAt", "updatedAt", "cnRef", "we", "confirmedDate"]
            }
          },
          {
            "name": "sortOrder",
            "in": "query",
            "required": false,
            "description": "Sort direction",
            "schema": {
              "type": "string",
              "enum": ["asc", "desc"]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Credit notes returned successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreditNotesListResponse"
                }
              }
            }
          }
        }
      }
    },
    "/credit-notes/{id}": {
      "get": {
        "summary": "Get credit note",
        "tags": ["Credit Notes"],
        "security": [
          {
            "BearerApiKey": ["read:credit-notes"]
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Credit note identifier",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Credit note returned successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreditNoteResponse"
                }
              }
            }
          }
        }
      }
    },
    "/invoices": {
      "get": {
        "summary": "List invoices",
        "tags": ["Invoices"],
        "security": [
          {
            "BearerApiKey": ["read:invoices"]
          }
        ],
        "parameters": [
          {
            "name": "company",
            "in": "query",
            "required": false,
            "description": "Filter by company id. If omitted, data for all companies linked to the API key is returned.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "Page number (default 1)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Records per page (default 50, max 200)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "Filter by invoice status",
            "schema": {
              "type": "string",
              "enum": ["pending", "confirmed"]
            }
          },
          {
            "name": "project",
            "in": "query",
            "required": false,
            "description": "Filter by project id",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "agency",
            "in": "query",
            "required": false,
            "description": "Filter by agency id",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "invoiceType",
            "in": "query",
            "required": false,
            "description": "Filter by invoice flow type",
            "schema": {
              "type": "string",
              "enum": ["supplierToClient", "supplierToMsp", "mspToClient"]
            }
          },
          {
            "name": "mspInvoiceType",
            "in": "query",
            "required": false,
            "description": "Filter by MSP invoice subtype",
            "schema": {
              "type": "string",
              "enum": ["receivable", "payable"]
            }
          },
          {
            "name": "query",
            "in": "query",
            "required": false,
            "description": "Case-insensitive search against invoice reference, contextual company/project/supplier/MSP names, and linked timesheet references",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "description": "Created date filter start (`YYYY-MM-DD`)",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "description": "Created date filter end (`YYYY-MM-DD`)",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "sortBy",
            "in": "query",
            "required": false,
            "description": "Sort field",
            "schema": {
              "type": "string",
              "enum": ["createdAt", "updatedAt", "invoiceRef", "due", "we", "confirmedDate"]
            }
          },
          {
            "name": "sortOrder",
            "in": "query",
            "required": false,
            "description": "Sort direction",
            "schema": {
              "type": "string",
              "enum": ["asc", "desc"]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Invoices returned successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvoicesListResponse"
                },
                "example": {
                  "success": true,
                  "data": [
                    {
                      "id": "67bc36db80a1616ec3f4b001",
                      "reference": "RDX-NLD-I1044",
                      "status": "pending",
                      "company": {
                        "id": "67bc36db80a1616ec3f47001",
                        "name": "Requidex Construction Ltd"
                      },
                      "agency": {
                        "id": "67bc36db80a1616ec3f47101",
                        "name": "Northline Labour Desk"
                      },
                      "projects": [
                        {
                          "id": "67bc36db80a1616ec3f47011",
                          "name": "Northern Rail Electrification"
                        }
                      ],
                      "invoiceType": "supplierToClient",
                      "mspInvoiceType": null,
                      "weekEnding": "2026-03-08T00:00:00.000Z",
                      "due": "2026-04-07T00:00:00.000Z",
                      "confirmedDate": null,
                      "values": {
                        "grossHours": 40,
                        "netHours": 37.5,
                        "subtotal": 1125,
                        "vat": 225,
                        "total": 1350,
                        "cis": 0,
                        "finalTotal": 1350,
                        "expenses": 125,
                        "creditNotes": 0,
                        "netValue": 1475
                      },
                      "files": {
                        "invoice": "https://files.requidex.com/invoices/INV-1044.pdf",
                        "timesheetSnapshot": "https://files.requidex.com/invoices/INV-1044-timesheets.pdf"
                      },
                      "timesheets": [
                        {
                          "id": "67bc36db80a1616ec3f4a001",
                          "reference": "TS-1044"
                        }
                      ],
                      "createdAt": "2026-03-08T18:00:00.000Z",
                      "updatedAt": "2026-03-08T18:05:00.000Z"
                    }
                  ],
                  "meta": {
                    "page": 1,
                    "limit": 50,
                    "total": 1
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, revoked, or expired API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden due to scope or IP restrictions",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "405": {
            "description": "Method not allowed on Open API routes",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected internal error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/invoices/{id}": {
      "get": {
        "summary": "Get invoice",
        "tags": ["Invoices"],
        "security": [
          {
            "BearerApiKey": ["read:invoices"]
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Invoice identifier",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Invoice returned successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvoiceResponse"
                },
                "example": {
                  "success": true,
                  "data": {
                    "id": "67bc36db80a1616ec3f4b001",
                    "reference": "RDX-NLD-I1044",
                    "status": "confirmed",
                    "company": {
                      "id": "67bc36db80a1616ec3f47001",
                      "name": "Requidex Construction Ltd"
                    },
                    "agency": {
                      "id": "67bc36db80a1616ec3f47101",
                      "name": "Northline Labour Desk"
                    },
                    "projects": [
                      {
                        "id": "67bc36db80a1616ec3f47011",
                        "name": "Northern Rail Electrification"
                      }
                    ],
                    "invoiceType": "supplierToClient",
                    "mspInvoiceType": null,
                    "weekEnding": "2026-03-08T00:00:00.000Z",
                    "due": "2026-04-07T00:00:00.000Z",
                    "confirmedDate": "2026-03-25T12:00:00.000Z",
                    "confirmedBy": {
                      "id": "67bc36db80a1616ec3f47099",
                      "name": "Pat Taylor"
                    },
                    "payment": {
                      "reference": "PAY-2044",
                      "paymentDate": "2026-03-25T12:00:00.000Z"
                    },
                    "values": {
                      "grossHours": 40,
                      "netHours": 37.5,
                      "subtotal": 1125,
                      "vat": 225,
                      "total": 1350,
                      "cis": 0,
                      "finalTotal": 1350,
                      "expenses": 125,
                      "creditNotes": 0,
                      "netValue": 1475
                    },
                    "files": {
                      "invoice": "https://files.requidex.com/invoices/INV-1044.pdf",
                      "timesheetSnapshot": "https://files.requidex.com/invoices/INV-1044-timesheets.pdf"
                    },
                    "timesheets": [
                      {
                        "id": "67bc36db80a1616ec3f4a001",
                        "reference": "TS-1044"
                      }
                    ],
                    "createdAt": "2026-03-08T18:00:00.000Z",
                    "updatedAt": "2026-03-25T12:00:00.000Z"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, revoked, or expired API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden due to scope or IP restrictions",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Invoice not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "405": {
            "description": "Method not allowed on Open API routes",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected internal error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/afps": {
      "get": {
        "summary": "List AfP",
        "tags": ["Invoices"],
        "security": [
          {
            "BearerApiKey": ["read:invoices"]
          }
        ],
        "parameters": [
          {
            "name": "company",
            "in": "query",
            "required": false,
            "description": "Filter by company id. If omitted, data for all companies linked to the API key is returned.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "Page number (default 1)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Records per page (default 50, max 200)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "Filter by AfP status",
            "schema": {
              "type": "string",
              "enum": ["pending", "confirmed"]
            }
          },
          {
            "name": "project",
            "in": "query",
            "required": false,
            "description": "Filter by project id",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "agency",
            "in": "query",
            "required": false,
            "description": "Filter by agency id",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "invoiceType",
            "in": "query",
            "required": false,
            "description": "Filter by AfP flow type",
            "schema": {
              "type": "string",
              "enum": ["supplierToClient", "supplierToMsp", "mspToClient"]
            }
          },
          {
            "name": "mspInvoiceType",
            "in": "query",
            "required": false,
            "description": "Filter by MSP AfP subtype",
            "schema": {
              "type": "string",
              "enum": ["receivable", "payable"]
            }
          },
          {
            "name": "query",
            "in": "query",
            "required": false,
            "description": "Case-insensitive search against AfP reference, contextual company/project/supplier/MSP names, and linked timesheet references",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "description": "Created date filter start (`YYYY-MM-DD`)",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "description": "Created date filter end (`YYYY-MM-DD`)",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "sortBy",
            "in": "query",
            "required": false,
            "description": "Sort field",
            "schema": {
              "type": "string",
              "enum": ["createdAt", "updatedAt", "invoiceRef", "due", "we", "confirmedDate"]
            }
          },
          {
            "name": "sortOrder",
            "in": "query",
            "required": false,
            "description": "Sort direction",
            "schema": {
              "type": "string",
              "enum": ["asc", "desc"]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "AfP returned successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvoicesListResponse"
                },
                "example": {
                  "success": true,
                  "data": [
                    {
                      "id": "67bc36db80a1616ec3f4b101",
                      "reference": "AFP-1044",
                      "status": "pending",
                      "company": {
                        "id": "67bc36db80a1616ec3f47001",
                        "name": "Requidex Construction Ltd"
                      },
                      "agency": {
                        "id": "67bc36db80a1616ec3f47101",
                        "name": "Northline Labour Desk"
                      },
                      "projects": [
                        {
                          "id": "67bc36db80a1616ec3f47011",
                          "name": "Northern Rail Electrification"
                        }
                      ],
                      "invoiceType": "supplierToClient",
                      "mspInvoiceType": null,
                      "weekEnding": "2026-03-08T00:00:00.000Z",
                      "due": "2026-04-07T00:00:00.000Z",
                      "confirmedDate": null,
                      "values": {
                        "grossHours": 40,
                        "netHours": 37.5,
                        "subtotal": 1125,
                        "vat": 225,
                        "total": 1350,
                        "cis": 0,
                        "finalTotal": 1350,
                        "expenses": 125,
                        "creditNotes": 0,
                        "netValue": 1475
                      },
                      "files": {
                        "invoice": "https://files.requidex.com/invoices/AFP-1044.pdf",
                        "timesheetSnapshot": "https://files.requidex.com/invoices/AFP-1044-timesheets.pdf"
                      },
                      "timesheets": [
                        {
                          "id": "67bc36db80a1616ec3f4a001",
                          "reference": "TS-1044"
                        }
                      ],
                      "createdAt": "2026-03-08T18:00:00.000Z",
                      "updatedAt": "2026-03-08T18:05:00.000Z"
                    }
                  ],
                  "meta": {
                    "page": 1,
                    "limit": 50,
                    "total": 1
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, revoked, or expired API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden due to scope or IP restrictions",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "405": {
            "description": "Method not allowed on Open API routes",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected internal error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/afps/{id}": {
      "get": {
        "summary": "Get AfP",
        "tags": ["Invoices"],
        "security": [
          {
            "BearerApiKey": ["read:invoices"]
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "AfP identifier",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "AfP returned successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvoiceResponse"
                },
                "example": {
                  "success": true,
                  "data": {
                    "id": "67bc36db80a1616ec3f4b101",
                    "reference": "AFP-1044",
                    "status": "confirmed",
                    "company": {
                      "id": "67bc36db80a1616ec3f47001",
                      "name": "Requidex Construction Ltd"
                    },
                    "agency": {
                      "id": "67bc36db80a1616ec3f47101",
                      "name": "Northline Labour Desk"
                    },
                    "projects": [
                      {
                        "id": "67bc36db80a1616ec3f47011",
                        "name": "Northern Rail Electrification"
                      }
                    ],
                    "invoiceType": "supplierToClient",
                    "mspInvoiceType": null,
                    "weekEnding": "2026-03-08T00:00:00.000Z",
                    "due": "2026-04-07T00:00:00.000Z",
                    "confirmedDate": "2026-03-25T12:00:00.000Z",
                    "confirmedBy": {
                      "id": "67bc36db80a1616ec3f47099",
                      "name": "Pat Taylor"
                    },
                    "payment": {
                      "reference": "PAY-2044",
                      "paymentDate": "2026-03-25T12:00:00.000Z"
                    },
                    "values": {
                      "grossHours": 40,
                      "netHours": 37.5,
                      "subtotal": 1125,
                      "vat": 225,
                      "total": 1350,
                      "cis": 0,
                      "finalTotal": 1350,
                      "expenses": 125,
                      "creditNotes": 0,
                      "netValue": 1475
                    },
                    "files": {
                      "invoice": "https://files.requidex.com/invoices/AFP-1044.pdf",
                      "timesheetSnapshot": "https://files.requidex.com/invoices/AFP-1044-timesheets.pdf"
                    },
                    "timesheets": [
                      {
                        "id": "67bc36db80a1616ec3f4a001",
                        "reference": "TS-1044"
                      }
                    ],
                    "createdAt": "2026-03-08T18:00:00.000Z",
                    "updatedAt": "2026-03-25T12:00:00.000Z"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, revoked, or expired API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden due to scope or IP restrictions",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "AfP not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "405": {
            "description": "Method not allowed on Open API routes",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected internal error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/afps/payment-notices": {
      "get": {
        "summary": "List Payment Notices",
        "tags": ["Invoices"],
        "security": [
          {
            "BearerApiKey": ["read:invoices"]
          }
        ],
        "parameters": [
          {
            "name": "company",
            "in": "query",
            "required": false,
            "description": "Filter by company id. If omitted, data for all companies linked to the API key is returned.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "Page number (default 1)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Records per page (default 50, max 200)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "Filter by payment notice status",
            "schema": {
              "type": "string",
              "enum": ["pending", "processed", "cancelled"]
            }
          },
          {
            "name": "query",
            "in": "query",
            "required": false,
            "description": "Case-insensitive search against payment notice reference, AfP reference, and notice comments",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "afp",
            "in": "query",
            "required": false,
            "description": "Filter by AfP id",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "description": "Created date filter start (`YYYY-MM-DD`)",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "description": "Created date filter end (`YYYY-MM-DD`)",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "sortBy",
            "in": "query",
            "required": false,
            "description": "Sort field",
            "schema": {
              "type": "string",
              "enum": ["createdAt", "updatedAt", "paymentNoticeRef", "processedDate"]
            }
          },
          {
            "name": "sortOrder",
            "in": "query",
            "required": false,
            "description": "Sort direction",
            "schema": {
              "type": "string",
              "enum": ["asc", "desc"]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Payment notices returned successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentNoticesListResponse"
                },
                "example": {
                  "success": true,
                  "data": [
                    {
                      "id": "67bc36db80a1616ec3f4d001",
                      "reference": "RDX-NLD-P1044",
                      "status": "pending",
                      "afp": {
                        "id": "67bc36db80a1616ec3f4b101",
                        "reference": "AFP-1044"
                      },
                      "company": {
                        "id": "67bc36db80a1616ec3f47001",
                        "name": "Requidex Construction Ltd"
                      },
                      "agency": {
                        "id": "67bc36db80a1616ec3f47101",
                        "name": "Northline Labour Desk"
                      },
                      "approvedAmount": 1225,
                      "disputedAmount": 125,
                      "comments": "Please see disputed item breakdown.",
                      "dispute": {
                        "comments": "One timesheet line is disputed pending review.",
                        "disputedItems": [
                          {
                            "timesheet": {
                              "id": "67bc36db80a1616ec3f4a001",
                              "reference": "TS-1044"
                            },
                            "expenseId": null,
                            "amount": 125,
                            "reason": "Hours exceed authorised shift"
                          }
                        ]
                      },
                      "processedDate": null,
                      "processedFile": null,
                      "cancellationComments": null,
                      "createdAt": "2026-03-20T09:15:00.000Z",
                      "updatedAt": "2026-03-20T09:15:00.000Z"
                    }
                  ],
                  "meta": {
                    "page": 1,
                    "limit": 50,
                    "total": 1
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, revoked, or expired API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden due to scope or IP restrictions",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "405": {
            "description": "Method not allowed on Open API routes",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected internal error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/afps/payment-notices/{id}": {
      "get": {
        "summary": "Get Payment Notice",
        "tags": ["Invoices"],
        "security": [
          {
            "BearerApiKey": ["read:invoices"]
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Payment notice identifier",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Payment notice returned successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentNoticeResponse"
                },
                "example": {
                  "success": true,
                  "data": {
                    "id": "67bc36db80a1616ec3f4d001",
                    "reference": "RDX-NLD-P1044",
                    "status": "processed",
                    "afp": {
                      "id": "67bc36db80a1616ec3f4b101",
                      "reference": "AFP-1044"
                    },
                    "company": {
                      "id": "67bc36db80a1616ec3f47001",
                      "name": "Requidex Construction Ltd"
                    },
                    "agency": {
                      "id": "67bc36db80a1616ec3f47101",
                      "name": "Northline Labour Desk"
                    },
                    "approvedAmount": 1350,
                    "disputedAmount": 0,
                    "comments": "Accepted in full.",
                    "processedDate": "2026-03-25T12:00:00.000Z",
                    "processedFile": {
                      "fileName": "AFP-1044-payment-notice.pdf",
                      "url": "https://files.requidex.com/payment-notices/AFP-1044-payment-notice.pdf",
                      "created": "2026-03-25T12:01:00.000Z"
                    },
                    "cancellationComments": null,
                    "createdAt": "2026-03-20T09:15:00.000Z",
                    "updatedAt": "2026-03-25T12:01:00.000Z"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, revoked, or expired API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden due to scope or IP restrictions",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Payment notice not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "405": {
            "description": "Method not allowed on Open API routes",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected internal error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/workers": {
      "get": {
        "summary": "List workers",
        "parameters": [
          {
            "name": "company",
            "in": "query",
            "required": false,
            "description": "Filter by company id. If omitted, workers for all companies linked to the API key are returned.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "Page number (default 1)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Records per page (default 50, max 200)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          },
          {
            "name": "query",
            "in": "query",
            "required": false,
            "description": "Case-insensitive search against worker name, reference, and email",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "includeDocumentValidations",
            "in": "query",
            "required": false,
            "description": "Include matching competency-validation rows for attachment and right-to-work documents. Non-system rows are limited to companies linked to the API key",
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "description": "Created date filter start (`YYYY-MM-DD`)",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "description": "Created date filter end (`YYYY-MM-DD`)",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "sortBy",
            "in": "query",
            "required": false,
            "description": "Sort field",
            "schema": {
              "type": "string",
              "enum": ["createdAt", "updatedAt", "name", "firstName", "lastName", "ref"]
            }
          },
          {
            "name": "sortOrder",
            "in": "query",
            "required": false,
            "description": "Sort direction",
            "schema": {
              "type": "string",
              "enum": ["asc", "desc"]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Workers returned successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkersListResponse"
                },
                "example": {
                  "success": true,
                  "data": [
                    {
                      "id": "67bc36db80a1616ec3f48999",
                      "reference": "WK-1001",
                      "firstName": "Jordan",
                      "lastName": "Smith",
                      "name": "Jordan Smith",
                      "gender": "male",
                      "nationalIns": "AB123456C",
                      "passportNo": "P1234567",
                      "nationality": "British",
                      "dob": "1990-01-01T00:00:00.000Z",
                      "phone": {
                        "countryCode": "+44",
                        "number": "1234567890"
                      },
                      "email": "jordan@example.com",
                      "address": {
                        "lineOne": "1 Main Street",
                        "city": "Manchester",
                        "country": "United Kingdom",
                        "code": "M1 1AA"
                      },
                      "agencies": [
                        {
                          "id": "67bc36db80a1616ec3f47101",
                          "name": "Northline Labour Desk",
                          "agencyId": "AG-1001",
                          "active": true
                        }
                      ],
                      "trades": [
                        {
                          "id": "67bc36db80a1616ec3f47102",
                          "name": "Electrician"
                        }
                      ],
                      "attachments": [
                        {
                          "id": "67bc36db80a1616ec3f48a10",
                          "type": "attachment",
                          "documentType": "CSCS Card",
                          "documentNumber": "CSCS-123",
                          "expiration": "2027-01-01T00:00:00.000Z",
                          "indefinite": false,
                          "createdAt": "2026-02-01T09:00:00.000Z",
                          "files": [
                            {
                              "fileName": "cscs-front.jpg",
                              "url": "https://files.requidex.com/cscs-front.jpg",
                              "docType": "Front"
                            }
                          ],
                          "verification": {
                            "verified": true,
                            "cardTypeName": "Gold Skilled Worker",
                            "serial": "CSCS-SERIAL-1",
                            "customerName": "Jordan Smith",
                            "documentNumber": "CSCS-123",
                            "photoType": "image/jpeg",
                            "expiry": "2027-01-01",
                            "occupationQualifications": [
                              {
                                "qual": "Electrician"
                              }
                            ],
                            "lastVerifiedAt": "2026-02-02T12:00:00.000Z"
                          },
                          "systemValidation": {
                            "status": "validated",
                            "checkedAt": "2026-02-02T12:00:00.000Z",
                            "documentType": "CSCS Card",
                            "reason": null
                          },
                          "validations": [
                            {
                              "id": "67bc36db80a1616ec3f48b01",
                              "company": {
                                "id": "67bc36db80a1616ec3f47001",
                                "name": "Requidex Construction Ltd"
                              },
                              "competency": {
                                "id": "67bc36db80a1616ec3f47234",
                                "name": "CSCS"
                              },
                              "user": {
                                "id": "67bc36db80a1616ec3f49998",
                                "name": "Alex Carter"
                              },
                              "validationType": "manual",
                              "status": "validated",
                              "resolvedAt": "2026-02-05T12:00:00.000Z",
                              "documentType": "attachment",
                              "documentRef": "67bc36db80a1616ec3f48a10",
                              "statusHistory": [
                                {
                                  "status": "validated",
                                  "changedAt": "2026-02-05T12:00:00.000Z",
                                  "changedBy": {
                                    "id": "67bc36db80a1616ec3f49998",
                                    "name": "Alex Carter"
                                  }
                                }
                              ],
                              "createdAt": "2026-02-05T12:00:00.000Z",
                              "updatedAt": "2026-02-05T12:00:00.000Z"
                            }
                          ]
                        }
                      ],
                      "rightToWork": [
                        {
                          "id": "67bc36db80a1616ec3f48a11",
                          "type": "rightToWork",
                          "documentType": "Passport",
                          "documentNumber": "P1234567",
                          "expiration": "2028-01-01T00:00:00.000Z",
                          "indefinite": false,
                          "createdAt": "2026-02-03T09:00:00.000Z",
                          "files": [
                            {
                              "fileName": "passport-front.jpg",
                              "url": "https://files.requidex.com/passport-front.jpg",
                              "docType": "Front"
                            }
                          ],
                          "systemValidation": {
                            "status": "validated",
                            "checkedAt": "2026-02-04T12:00:00.000Z",
                            "documentType": "Passport",
                            "reason": null
                          },
                          "validations": [
                            {
                              "id": "67bc36db80a1616ec3f48b02",
                              "company": {
                                "id": "67bc36db80a1616ec3f47001",
                                "name": "Requidex Construction Ltd"
                              },
                              "competency": null,
                              "user": {
                                "id": "67bc36db80a1616ec3f49997",
                                "name": "Pat Taylor"
                              },
                              "validationType": "manual",
                              "status": "validated",
                              "resolvedAt": "2026-02-06T12:00:00.000Z",
                              "documentType": "rightToWork",
                              "documentRef": "67bc36db80a1616ec3f48a11",
                              "statusHistory": [],
                              "createdAt": "2026-02-06T12:00:00.000Z",
                              "updatedAt": "2026-02-06T12:00:00.000Z"
                            }
                          ]
                        }
                      ],
                      "createdAt": "2026-01-15T10:00:00.000Z",
                      "updatedAt": "2026-02-10T14:00:00.000Z"
                    }
                  ],
                  "meta": {
                    "page": 1,
                    "limit": 50,
                    "total": 1
                  }
                }
              }
            }
          }
        }
      }
    },
    "/workers/{id}": {
      "get": {
        "summary": "Get worker",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Worker identifier",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "includeDocumentValidations",
            "in": "query",
            "required": false,
            "description": "Include matching competency-validation rows for attachment and right-to-work documents. Non-system rows are limited to companies linked to the API key",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Worker returned successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkerResponse"
                },
                "example": {
                  "success": true,
                  "data": {
                    "id": "67bc36db80a1616ec3f48999",
                    "reference": "WK-1001",
                    "firstName": "Jordan",
                    "lastName": "Smith",
                    "name": "Jordan Smith",
                    "gender": "male",
                    "nationalIns": "AB123456C",
                    "passportNo": "P1234567",
                    "nationality": "British",
                    "dob": "1990-01-01T00:00:00.000Z",
                    "phone": {
                      "countryCode": "+44",
                      "number": "1234567890"
                    },
                    "email": "jordan@example.com",
                    "address": {
                      "lineOne": "1 Main Street",
                      "city": "Manchester",
                      "country": "United Kingdom",
                      "code": "M1 1AA"
                    },
                    "agencies": [
                      {
                        "id": "67bc36db80a1616ec3f47101",
                        "name": "Northline Labour Desk",
                        "agencyId": "AG-1001",
                        "active": true
                      }
                    ],
                    "trades": [
                      {
                        "id": "67bc36db80a1616ec3f47102",
                        "name": "Electrician"
                      }
                    ],
                    "attachments": [
                      {
                        "id": "67bc36db80a1616ec3f48a10",
                        "type": "attachment",
                        "documentType": "CSCS Card",
                        "documentNumber": "CSCS-123",
                        "expiration": "2027-01-01T00:00:00.000Z",
                        "indefinite": false,
                        "createdAt": "2026-02-01T09:00:00.000Z",
                        "files": [
                          {
                            "fileName": "cscs-front.jpg",
                            "url": "https://files.requidex.com/cscs-front.jpg",
                            "docType": "Front"
                          }
                        ],
                        "verification": {
                          "verified": true,
                          "cardTypeName": "Gold Skilled Worker",
                          "serial": "CSCS-SERIAL-1",
                          "customerName": "Jordan Smith",
                          "documentNumber": "CSCS-123",
                          "photoType": "image/jpeg",
                          "expiry": "2027-01-01",
                          "occupationQualifications": [
                            {
                              "qual": "Electrician"
                            }
                          ],
                          "lastVerifiedAt": "2026-02-02T12:00:00.000Z"
                        },
                        "systemValidation": {
                          "status": "validated",
                          "checkedAt": "2026-02-02T12:00:00.000Z",
                          "documentType": "CSCS Card",
                          "reason": null
                        },
                        "validations": [
                          {
                            "id": "67bc36db80a1616ec3f48b01",
                            "company": {
                              "id": "67bc36db80a1616ec3f47001",
                              "name": "Requidex Construction Ltd"
                            },
                            "competency": {
                              "id": "67bc36db80a1616ec3f47234",
                              "name": "CSCS"
                            },
                            "user": {
                              "id": "67bc36db80a1616ec3f49998",
                              "name": "Alex Carter"
                            },
                            "validationType": "manual",
                            "status": "validated",
                            "resolvedAt": "2026-02-05T12:00:00.000Z",
                            "documentType": "attachment",
                            "documentRef": "67bc36db80a1616ec3f48a10",
                            "statusHistory": [
                              {
                                "status": "validated",
                                "changedAt": "2026-02-05T12:00:00.000Z",
                                "changedBy": {
                                  "id": "67bc36db80a1616ec3f49998",
                                  "name": "Alex Carter"
                                }
                              }
                            ],
                            "createdAt": "2026-02-05T12:00:00.000Z",
                            "updatedAt": "2026-02-05T12:00:00.000Z"
                          }
                        ]
                      }
                    ],
                    "rightToWork": [
                      {
                        "id": "67bc36db80a1616ec3f48a11",
                        "type": "rightToWork",
                        "documentType": "Passport",
                        "documentNumber": "P1234567",
                        "expiration": "2028-01-01T00:00:00.000Z",
                        "indefinite": false,
                        "createdAt": "2026-02-03T09:00:00.000Z",
                        "files": [
                          {
                            "fileName": "passport-front.jpg",
                            "url": "https://files.requidex.com/passport-front.jpg",
                            "docType": "Front"
                          }
                        ],
                        "systemValidation": {
                          "status": "validated",
                          "checkedAt": "2026-02-04T12:00:00.000Z",
                          "documentType": "Passport",
                          "reason": null
                        },
                        "validations": [
                          {
                            "id": "67bc36db80a1616ec3f48b02",
                            "company": {
                              "id": "67bc36db80a1616ec3f47001",
                              "name": "Requidex Construction Ltd"
                            },
                            "competency": null,
                            "user": {
                              "id": "67bc36db80a1616ec3f49997",
                              "name": "Pat Taylor"
                            },
                            "validationType": "manual",
                            "status": "validated",
                            "resolvedAt": "2026-02-06T12:00:00.000Z",
                            "documentType": "rightToWork",
                            "documentRef": "67bc36db80a1616ec3f48a11",
                            "statusHistory": [],
                            "createdAt": "2026-02-06T12:00:00.000Z",
                            "updatedAt": "2026-02-06T12:00:00.000Z"
                          }
                        ]
                      }
                    ],
                    "createdAt": "2026-01-15T10:00:00.000Z",
                    "updatedAt": "2026-02-10T14:00:00.000Z"
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}
