{
  "openapi": "3.1.0",
  "info": {
    "title": "GroundIT — Expense & Benefits",
    "version": "0.1.0",
    "license": {
      "name": "Proprietary — GroundIT/Sysmedac internal"
    },
    "description": "Out-of-pocket reimbursement claims with itemised, object-stored receipts; configurable expense-policy and per-diem controls evaluated and stamped synchronously at submit; the pre-trip-to-settlement business-travel loop (multi-leg itinerary, maker-checker cash advances, advance-to-actuals reconciliation) — all `expense.*`. Pack-driven benefit plans (GMC/GPA/GTL/FBP/…), employee + dependent enrolment, per-member insurance records / e-cards, and the India-leaning flexible benefit plan (FBP) declaration/verify/lock cycle that feeds payroll and India investment tax by event — `benefits.*`. See ../../api-docs/00-api-overview-and-conventions.md.\n"
  },
  "servers": [
    {
      "url": "/api/v1"
    }
  ],
  "security": [
    {
      "bearerJWT": []
    }
  ],
  "tags": [
    {
      "name": "expense",
      "description": "Reimbursement claims + receipts, business travel (requests/legs/advances), expense-policy & per-diem config."
    },
    {
      "name": "benefits",
      "description": "Benefit plans, enrolment, insurance records / e-cards, flexible benefit plan (FBP) declarations."
    }
  ],
  "x-reuse-anchors": {
    "parameters": {
      "path_id": {
        "$ref": "#/components/parameters/PathId"
      },
      "page_size": {
        "$ref": "#/components/parameters/PageSize"
      },
      "page_after": {
        "$ref": "#/components/parameters/PageAfter"
      },
      "page_before": {
        "$ref": "#/components/parameters/PageBefore"
      },
      "sort_param": {
        "$ref": "#/components/parameters/SortParam"
      },
      "accept_language": {
        "$ref": "#/components/parameters/AcceptLanguage"
      },
      "idempotency_key": {
        "$ref": "#/components/parameters/IdempotencyKey"
      },
      "if_match": {
        "$ref": "#/components/parameters/IfMatch"
      }
    },
    "responses": {
      "unauthorized": {
        "$ref": "#/components/responses/Unauthorized"
      },
      "forbidden": {
        "$ref": "#/components/responses/Forbidden"
      },
      "not_found": {
        "$ref": "#/components/responses/NotFound"
      },
      "conflict": {
        "$ref": "#/components/responses/Conflict"
      },
      "unprocessable": {
        "$ref": "#/components/responses/UnprocessableEntity"
      },
      "locked": {
        "$ref": "#/components/responses/Locked"
      },
      "too_many": {
        "$ref": "#/components/responses/TooManyRequests"
      },
      "precondition_required": {
        "$ref": "#/components/responses/PreconditionRequired"
      },
      "precondition_failed": {
        "$ref": "#/components/responses/PreconditionFailed"
      }
    },
    "headers": {
      "etag": {
        "$ref": "#/components/headers/ETag"
      },
      "location": {
        "$ref": "#/components/headers/Location"
      },
      "idem_replayed": {
        "$ref": "#/components/headers/IdempotencyReplayed"
      }
    }
  },
  "paths": {
    "/expense-claims": {
      "post": {
        "operationId": "expense.expense_claim.create",
        "summary": "Raise a reimbursement claim (with its receipts), or link an advance settlement",
        "description": "The New-claim sheet's **Submit** (EXP-S02) — creates `expense.expense_claims` with its itemised `receipts` in one call. By default the claim is submitted immediately (`DRAFT`→`SUBMITTED` atomically) and **synchronously evaluates** the applicable `expense_policies`/`per_diem_rates`, stamping the decision onto `policy_snapshot` (EXP-F04, db 08 §1.2); set `save_as_draft: true` to persist a `DRAFT` only (EXP-S04 \"a DRAFT is editable\"), evaluated later on an explicit submit via `expense.expense_claim.update`. `claim_type` is server-derived from `travel_request_id` presence (`TRAVEL` when linked, else `REIMBURSEMENT`) unless the caller explicitly sends `claim_type: ADVANCE_SETTLEMENT` — the post-trip claim EXP-S09 files to reconcile a `travel_advance` (the advance's `settlement_claim_id` back-fills once this claim is created; the advance's `PENDING_SETTLEMENT → SETTLED/RECOVERED` transition and payroll net routing happen on Finance's `expense.travel_advance.settle`, EXP-S12, once this claim is `APPROVED`). Routed to the approver via the unified inbox (XC-F12) on submit.\n",
        "tags": [
          "expense",
          "expense_claim"
        ],
        "x-token": "expense.expense_claim.create",
        "x-realizes-features": [
          "EXP-F01",
          "EXP-F03",
          "EXP-F04"
        ],
        "x-screens": [
          "EXP-S02",
          "EXP-S03",
          "EXP-S09"
        ],
        "x-touches-entities": [
          "expense.expense_claims",
          "expense.receipts",
          "expense.expense_policies",
          "expense.per_diem_rates",
          "expense.travel_requests",
          "expense.travel_advances",
          "people.employees"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "expense.expense_claim.submitted",
        "x-rls-scope": "self",
        "x-append-only": false,
        "x-entitlement": "expense",
        "x-provisional": null,
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ExpenseClaimCreate"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Claim created. `SUBMITTED` (with `policy_snapshot` stamped) unless `save_as_draft: true` — the EXP-S03 confirmation payload (`claim_no`, `submitted_at`, `claimed_amount`) is this response's contract (subsumed by the New-claim sheet's toast, design-docs/03 N-08).\n",
            "headers": {
              "Location": {
                "$ref": "#/components/headers/Location"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "Idempotency-Replayed": {
                "$ref": "#/components/headers/IdempotencyReplayed"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExpenseClaim"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "get": {
        "operationId": "expense.expense_claim.list",
        "summary": "My reimbursement claims",
        "description": "The employee's own claims by status/category, searchable (EXP-S01 Money-tab claims list).",
        "tags": [
          "expense",
          "expense_claim"
        ],
        "x-token": "expense.expense_claim.list",
        "x-realizes-features": [
          "EXP-F01"
        ],
        "x-screens": [
          "EXP-S01"
        ],
        "x-touches-entities": [
          "expense.expense_claims"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "self",
        "x-append-only": false,
        "x-entitlement": "expense",
        "x-provisional": null,
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": false,
            "description": "Free-text search over `title`/`claim_no` (client filter per EXP-S01, honoured server-side for parity).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/ExpenseClaimStatus"
            }
          },
          {
            "name": "category",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/ExpenseCategory"
            }
          },
          {
            "name": "claim_type",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/ExpenseClaimType"
            }
          },
          {
            "name": "expense_date[from]",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/DateOnlyRef"
            }
          },
          {
            "name": "expense_date[to]",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/DateOnlyRef"
            }
          },
          {
            "$ref": "#/components/parameters/PageSize"
          },
          {
            "$ref": "#/components/parameters/PageAfter"
          },
          {
            "$ref": "#/components/parameters/PageBefore"
          },
          {
            "name": "sort",
            "in": "query",
            "required": false,
            "description": "Sort whitelist: `expense_date`, `-expense_date`, `status`. Default `-expense_date`.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Page of the caller's own claims.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExpenseClaimPage"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/expense-claims/{id}": {
      "get": {
        "operationId": "expense.expense_claim.get",
        "summary": "Get one reimbursement claim (detail)",
        "description": "The full claim — amounts, receipts, policy result, approval trail, and payout once reimbursed (EXP-S04).",
        "tags": [
          "expense",
          "expense_claim"
        ],
        "x-token": "expense.expense_claim.get",
        "x-realizes-features": [
          "EXP-F01"
        ],
        "x-screens": [
          "EXP-S04"
        ],
        "x-touches-entities": [
          "expense.expense_claims",
          "expense.receipts",
          "expense.travel_requests",
          "people.employees"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "self",
        "x-append-only": false,
        "x-entitlement": "expense",
        "x-provisional": null,
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          }
        ],
        "responses": {
          "200": {
            "description": "The claim with its receipts, policy snapshot, and approval/payout state.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExpenseClaimDetail"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "patch": {
        "operationId": "expense.expense_claim.update",
        "summary": "Edit a draft claim (or submit it)",
        "description": "Edits a `DRAFT` claim's header/receipts (EXP-S04 \"Edit\" → `EXP-S02` prefilled); set `submit: true` to transition `DRAFT → SUBMITTED`, synchronously evaluating and stamping `policy_snapshot` (EXP-F04). 409 `STATE_TRANSITION_INVALID` once the claim has left `DRAFT`.\n",
        "tags": [
          "expense",
          "expense_claim"
        ],
        "x-token": "expense.expense_claim.update",
        "x-realizes-features": [
          "EXP-F01",
          "EXP-F04"
        ],
        "x-screens": [
          "EXP-S04"
        ],
        "x-touches-entities": [
          "expense.expense_claims",
          "expense.receipts",
          "expense.expense_policies",
          "expense.per_diem_rates"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "expense.expense_claim.submitted",
        "x-rls-scope": "self",
        "x-append-only": false,
        "x-entitlement": "expense",
        "x-provisional": null,
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "name": "If-Match",
            "in": "header",
            "required": true,
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ExpenseClaimUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated (and, if `submit: true`, now `SUBMITTED`).",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "Idempotency-Replayed": {
                "$ref": "#/components/headers/IdempotencyReplayed"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExpenseClaim"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "428": {
            "$ref": "#/components/responses/PreconditionRequired"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/expense-claims/{id}/cancel": {
      "post": {
        "operationId": "expense.expense_claim.cancel",
        "summary": "Cancel a claim (pre-approval)",
        "description": "`CANCELLED` from any pre-`APPROVED` state (EXP-S04). 409 `STATE_TRANSITION_INVALID` once `APPROVED`+.",
        "tags": [
          "expense",
          "expense_claim"
        ],
        "x-token": "expense.expense_claim.cancel",
        "x-realizes-features": [
          "EXP-F01"
        ],
        "x-screens": [
          "EXP-S04"
        ],
        "x-touches-entities": [
          "expense.expense_claims"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "expense.expense_claim.cancelled",
        "x-rls-scope": "self",
        "x-append-only": false,
        "x-entitlement": "expense",
        "x-provisional": null,
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "name": "If-Match",
            "in": "header",
            "required": true,
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DecisionNoteInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Cancelled.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "Idempotency-Replayed": {
                "$ref": "#/components/headers/IdempotencyReplayed"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExpenseClaim"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "428": {
            "$ref": "#/components/responses/PreconditionRequired"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/expense-claims/admin": {
      "get": {
        "operationId": "expense.expense_claim.list_admin",
        "summary": "Finance's claim review queue",
        "description": "The Finance claim queue across the workforce — pending / approved-pending-payment / paid / all (EXP-S10), with the manager-approval step surfaced upstream (`XC-F12`).\n",
        "tags": [
          "expense",
          "expense_claim"
        ],
        "x-token": "expense.expense_claim.list_admin",
        "x-realizes-features": [
          "EXP-F01"
        ],
        "x-screens": [
          "EXP-S10"
        ],
        "x-touches-entities": [
          "expense.expense_claims"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": "expense",
        "x-provisional": null,
        "parameters": [
          {
            "name": "employee_id",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/UuidRef"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/ExpenseClaimStatus"
            }
          },
          {
            "name": "claim_type",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/ExpenseClaimType"
            }
          },
          {
            "name": "category",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/ExpenseCategory"
            }
          },
          {
            "name": "expense_date[from]",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/DateOnlyRef"
            }
          },
          {
            "name": "expense_date[to]",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/DateOnlyRef"
            }
          },
          {
            "$ref": "#/components/parameters/PageSize"
          },
          {
            "$ref": "#/components/parameters/PageAfter"
          },
          {
            "$ref": "#/components/parameters/PageBefore"
          },
          {
            "name": "sort",
            "in": "query",
            "required": false,
            "description": "Sort whitelist: `expense_date`, `-expense_date`, `status`, `-status`.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Tenant-wide page of claims, each naming its claimant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExpenseClaimAdminPage"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/expense-claims/admin/exports": {
      "post": {
        "operationId": "expense.expense_claim.export",
        "summary": "Export the claim queue",
        "description": "Generates a capped, filtered CSV export of the claim queue (EXP-S10 **Export**).",
        "tags": [
          "expense",
          "expense_claim"
        ],
        "x-token": "expense.expense_claim.export",
        "x-realizes-features": [
          "EXP-F01"
        ],
        "x-screens": [
          "EXP-S10"
        ],
        "x-touches-entities": [
          "expense.expense_claims"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": "expense",
        "x-provisional": null,
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ExpenseClaimExportRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Presigned download handle for the generated export.",
            "headers": {
              "Idempotency-Replayed": {
                "$ref": "#/components/headers/IdempotencyReplayed"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FileDownloadRef"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/expense-claims/admin/summary": {
      "get": {
        "operationId": "expense.expense_claim.summary_admin",
        "summary": "The Finance queue's KPI tiles",
        "description": "The three `PT-KPI` bands above the EXP-S10 queue (fsd 07 §W1): claims still awaiting Finance, claims cleared but not yet paid, and what was actually reimbursed this period. Gated on the **queue's own token** (`expense.expense_claim.list_admin`), not one of its own — a summary is an aggregate of exactly the rows the caller can already page through, and a separate grant could only make the tiles disagree with the grid beneath them. Accepts the same filters as the queue, so the tiles describe the reviewer's current view. Totals are **per book currency, never summed across currencies** — a tenant may run an INR and a SAR entity side by side, and adding two currencies produces a number that is not money.\n",
        "tags": [
          "expense",
          "expense_claim"
        ],
        "x-token": "expense.expense_claim.list_admin",
        "x-realizes-features": [
          "EXP-F01"
        ],
        "x-screens": [
          "EXP-S10"
        ],
        "x-touches-entities": [
          "expense.expense_claims"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": "expense",
        "x-provisional": null,
        "parameters": [
          {
            "name": "employee_id",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/UuidRef"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/ExpenseClaimStatus"
            }
          },
          {
            "name": "claim_type",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/ExpenseClaimType"
            }
          },
          {
            "name": "category",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/ExpenseCategory"
            }
          },
          {
            "name": "expense_date[from]",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/DateOnlyRef"
            }
          },
          {
            "name": "expense_date[to]",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/DateOnlyRef"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Counts and per-currency totals for the three queue bands.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExpenseClaimQueueSummary"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/expense-claims/admin/{id}": {
      "get": {
        "operationId": "expense.expense_claim.get_admin",
        "summary": "One queue row with its receipts (Finance)",
        "description": "The EXP-S10 receipt-viewer `PT-DETAIL` drawer's read — one claim plus its `receipts`, each with a short-lived presigned download URL. **A distinct operation from `expense.expense_claim.get`, which cannot serve this:** `.get` is `x-rls-scope: self` and resolves the row by `(id, employee_id)`, so it 404s for every reviewer who is not the claimant, and the Finance role does not hold it. Gated on `expense.expense_claim.list_admin` — opening a row that is already on screen is a read of one row of that same list, not a new privilege.\n",
        "tags": [
          "expense",
          "expense_claim"
        ],
        "x-token": "expense.expense_claim.list_admin",
        "x-realizes-features": [
          "EXP-F01"
        ],
        "x-screens": [
          "EXP-S10"
        ],
        "x-touches-entities": [
          "expense.expense_claims",
          "expense.receipts"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": "expense",
        "x-provisional": null,
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          }
        ],
        "responses": {
          "200": {
            "description": "The claim, its claimant's display identity, its receipt summary and its receipts.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExpenseClaimAdminDetail"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/expense-claims/{id}/approve": {
      "post": {
        "operationId": "expense.expense_claim.approve",
        "summary": "Finance-approve a reimbursement claim",
        "description": "Sets `status='APPROVED'`, `approved_by`/`approved_at`/`approved_amount` (≤ `base_amount` after policy caps, db 08 §1.1 check) — Finance's decision, upstream of manager approval via the inbox (`XC-F12`, EXP-S10). Audited (`XC-F06`).\n",
        "tags": [
          "expense",
          "expense_claim"
        ],
        "x-token": "expense.expense_claim.approve",
        "x-realizes-features": [
          "EXP-F01"
        ],
        "x-screens": [
          "EXP-S10"
        ],
        "x-touches-entities": [
          "expense.expense_claims"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "expense.expense_claim.approved",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": "expense",
        "x-provisional": null,
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "name": "If-Match",
            "in": "header",
            "required": true,
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ExpenseClaimApprovalInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Approved.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "Idempotency-Replayed": {
                "$ref": "#/components/headers/IdempotencyReplayed"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExpenseClaim"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "428": {
            "$ref": "#/components/responses/PreconditionRequired"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/expense-claims/{id}/reject": {
      "post": {
        "operationId": "expense.expense_claim.reject",
        "summary": "Reject a reimbursement claim",
        "description": "`status='REJECTED'` with a `decision_note` reason, shown to the employee on EXP-S04 (EXP-S10, db 08 §1.5 gap fix). Audited (`XC-F06`).",
        "tags": [
          "expense",
          "expense_claim"
        ],
        "x-token": "expense.expense_claim.reject",
        "x-realizes-features": [
          "EXP-F01"
        ],
        "x-screens": [
          "EXP-S10"
        ],
        "x-touches-entities": [
          "expense.expense_claims"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "expense.expense_claim.rejected",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": "expense",
        "x-provisional": null,
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "name": "If-Match",
            "in": "header",
            "required": true,
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DecisionNoteInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Rejected.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "Idempotency-Replayed": {
                "$ref": "#/components/headers/IdempotencyReplayed"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExpenseClaim"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "428": {
            "$ref": "#/components/responses/PreconditionRequired"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/expense-claims/{id}/mark-paid": {
      "post": {
        "operationId": "expense.expense_claim.mark_paid",
        "summary": "Mark an approved claim paid (add to payroll / separate payout)",
        "description": "EXP-S10 **Mark Paid / Add to Payroll** — records a reimbursement that has been paid, stamping `reimbursed_at` and moving `APPROVED → REIMBURSED` (a claim already picked up by a payment run, `REIMBURSING`, is equally markable). This is the producer of the employee-facing `Paid` state per design-ess/06 §3, which is binding here: the action records a settlement that already happened, so the terminal status is written synchronously rather than promised asynchronously. `REIMBURSING` remains the payment run's own pickup state. Batch mark-paid notifies the employee (`XC-F05`). Audited (`XC-F06`).\n",
        "tags": [
          "expense",
          "expense_claim"
        ],
        "x-token": "expense.expense_claim.mark_paid",
        "x-realizes-features": [
          "EXP-F01"
        ],
        "x-screens": [
          "EXP-S10"
        ],
        "x-touches-entities": [
          "expense.expense_claims"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "expense.expense_claim.reimbursed",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": "expense",
        "x-provisional": null,
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "name": "If-Match",
            "in": "header",
            "required": true,
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DecisionNoteInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Recorded — the claim is `REIMBURSED` and carries its `reimbursed_at`.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "Idempotency-Replayed": {
                "$ref": "#/components/headers/IdempotencyReplayed"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExpenseClaim"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "428": {
            "$ref": "#/components/responses/PreconditionRequired"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/receipts/{id}/verify": {
      "post": {
        "operationId": "expense.receipt.verify",
        "summary": "Verify, reject, or flag a receipt as a duplicate",
        "description": "Finance's per-receipt decision from the EXP-S10 receipt-viewer drawer — writes `receipts.status` (`VERIFIED`/`REJECTED`/`DUPLICATE`); `VERIFIED` requires `content_hash` be present (db 08 §1.1 tamper-evidence check). `DUPLICATE` flags a re-submission by `content_hash` match.\n",
        "tags": [
          "expense",
          "receipt"
        ],
        "x-token": "expense.receipt.verify",
        "x-realizes-features": [
          "EXP-F01"
        ],
        "x-screens": [
          "EXP-S10"
        ],
        "x-touches-entities": [
          "expense.receipts",
          "expense.expense_claims"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "expense.receipt.reviewed",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": "expense",
        "x-provisional": null,
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "name": "If-Match",
            "in": "header",
            "required": true,
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReceiptReviewInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Receipt status updated.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "Idempotency-Replayed": {
                "$ref": "#/components/headers/IdempotencyReplayed"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Receipt"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "428": {
            "$ref": "#/components/responses/PreconditionRequired"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/travel-requests": {
      "post": {
        "operationId": "expense.travel_request.create",
        "summary": "Raise a multi-leg travel request",
        "description": "EXP-S06's **Submit** — creates `expense.travel_requests` (`DRAFT`→`SUBMITTED`) with its `travel_legs` in one call; **synchronously evaluates and stamps** the per-trip `policy_snapshot` (EXP-F04) against `expense.expense_policies` (`category = 'TRAVEL'`). A `DOMESTIC` trip must book in the entity's `base_currency_code` (db 08 §1.3 check); only `INTERNATIONAL` may carry a foreign `currency_code`, and every leg must be quoted in the trip's own `currency_code` (no exchange-rate source is wired for this surface). **As built** (`GAP-42`, `api-docs/05-traceability-and-coverage.md`), two things this operation does NOT yet do: it stamps every leg's `per_diem_amount` `null` rather than evaluating it — no `leg_type → per_diem_category` mapping has ever been decided. It lands in `SUBMITTED`; the tenant-scoped travel approval queue can decide it even while XC has no `TRAVEL` route member.\n",
        "tags": [
          "expense",
          "travel_request"
        ],
        "x-token": "expense.travel_request.create",
        "x-realizes-features": [
          "EXP-F02",
          "EXP-F04"
        ],
        "x-screens": [
          "EXP-S06"
        ],
        "x-touches-entities": [
          "expense.travel_requests",
          "expense.travel_legs",
          "expense.per_diem_rates",
          "people.employees"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "expense.travel_request.submitted",
        "x-rls-scope": "self",
        "x-append-only": false,
        "x-entitlement": "expense",
        "x-provisional": null,
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TravelRequestCreate"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Travel request created, `SUBMITTED`, with its itinerary and stamped policy/per-diem decision.",
            "headers": {
              "Location": {
                "$ref": "#/components/headers/Location"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "Idempotency-Replayed": {
                "$ref": "#/components/headers/IdempotencyReplayed"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRequest"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "get": {
        "operationId": "expense.travel_request.list",
        "summary": "My travel requests",
        "description": "The employee's own trips by status (EXP-S05).",
        "tags": [
          "expense",
          "travel_request"
        ],
        "x-token": "expense.travel_request.list",
        "x-realizes-features": [
          "EXP-F02"
        ],
        "x-screens": [
          "EXP-S05"
        ],
        "x-touches-entities": [
          "expense.travel_requests"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "self",
        "x-append-only": false,
        "x-entitlement": "expense",
        "x-provisional": null,
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/TravelRequestStatus"
            }
          },
          {
            "name": "trip_type",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/TripType"
            }
          },
          {
            "name": "start_date[from]",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/DateOnlyRef"
            }
          },
          {
            "name": "start_date[to]",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/DateOnlyRef"
            }
          },
          {
            "$ref": "#/components/parameters/PageSize"
          },
          {
            "$ref": "#/components/parameters/PageAfter"
          },
          {
            "$ref": "#/components/parameters/PageBefore"
          },
          {
            "name": "sort",
            "in": "query",
            "required": false,
            "description": "Sort whitelist: `start_date`, `-start_date`, `status`. Default `-start_date`.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Page of the caller's own travel requests.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRequestPage"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/travel-requests/{id}": {
      "get": {
        "operationId": "expense.travel_request.get",
        "summary": "Get one travel request (detail)",
        "description": "The trip end to end — itinerary, approval state, any advance, and settling claims (EXP-S07).",
        "tags": [
          "expense",
          "travel_request"
        ],
        "x-token": "expense.travel_request.get",
        "x-realizes-features": [
          "EXP-F02",
          "EXP-F03"
        ],
        "x-screens": [
          "EXP-S07"
        ],
        "x-touches-entities": [
          "expense.travel_requests",
          "expense.travel_legs",
          "expense.travel_advances",
          "expense.expense_claims",
          "people.employees"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "self",
        "x-append-only": false,
        "x-entitlement": "expense",
        "x-provisional": null,
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          }
        ],
        "responses": {
          "200": {
            "description": "The trip with its legs, any advance, and linked claims.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRequestDetail"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/travel-requests/{id}/cancel": {
      "post": {
        "operationId": "expense.travel_request.cancel",
        "summary": "Cancel a travel request (pre-booking)",
        "description": "`CANCELLED` pre-`BOOKED` (EXP-S07). 409 `STATE_TRANSITION_INVALID` once `BOOKED`+.",
        "tags": [
          "expense",
          "travel_request"
        ],
        "x-token": "expense.travel_request.cancel",
        "x-realizes-features": [
          "EXP-F02"
        ],
        "x-screens": [
          "EXP-S07"
        ],
        "x-touches-entities": [
          "expense.travel_requests"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "expense.travel_request.cancelled",
        "x-rls-scope": "self",
        "x-append-only": false,
        "x-entitlement": "expense",
        "x-provisional": null,
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "name": "If-Match",
            "in": "header",
            "required": true,
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DecisionNoteInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Cancelled.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "Idempotency-Replayed": {
                "$ref": "#/components/headers/IdempotencyReplayed"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRequest"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "428": {
            "$ref": "#/components/responses/PreconditionRequired"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/travel-requests/admin": {
      "get": {
        "operationId": "expense.travel_request.list_admin",
        "summary": "Manager/Finance travel-approval queue",
        "description": "The itinerary, per-diem/policy check, and approve/reject decision across the workforce (EXP-S11).",
        "tags": [
          "expense",
          "travel_request"
        ],
        "x-token": "expense.travel_request.list_admin",
        "x-realizes-features": [
          "EXP-F02"
        ],
        "x-screens": [
          "EXP-S11"
        ],
        "x-touches-entities": [
          "expense.travel_requests",
          "expense.travel_legs"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": "expense",
        "x-provisional": null,
        "parameters": [
          {
            "name": "employee_id",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/UuidRef"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/TravelRequestStatus"
            }
          },
          {
            "name": "trip_type",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/TripType"
            }
          },
          {
            "name": "start_date[from]",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/DateOnlyRef"
            }
          },
          {
            "name": "start_date[to]",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/DateOnlyRef"
            }
          },
          {
            "$ref": "#/components/parameters/PageSize"
          },
          {
            "$ref": "#/components/parameters/PageAfter"
          },
          {
            "$ref": "#/components/parameters/PageBefore"
          },
          {
            "name": "sort",
            "in": "query",
            "required": false,
            "description": "Sort whitelist: `start_date`, `-start_date`, `status`, `employee_id`.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Tenant-wide page of travel requests.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRequestPage"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/travel-requests/{id}/approve": {
      "post": {
        "operationId": "expense.travel_request.approve",
        "summary": "Approve a travel request",
        "description": "`status='APPROVED'` (`approved_by`/`approved_at`); routed via the inbox (`XC-F12`), honours delegation (`XC-F14`) (EXP-S11). Audited (`XC-F06`).",
        "tags": [
          "expense",
          "travel_request"
        ],
        "x-token": "expense.travel_request.approve",
        "x-realizes-features": [
          "EXP-F02"
        ],
        "x-screens": [
          "EXP-S11"
        ],
        "x-touches-entities": [
          "expense.travel_requests"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "expense.travel_request.approved",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": "expense",
        "x-provisional": null,
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "name": "If-Match",
            "in": "header",
            "required": true,
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DecisionNoteInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Approved.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "Idempotency-Replayed": {
                "$ref": "#/components/headers/IdempotencyReplayed"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRequest"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "428": {
            "$ref": "#/components/responses/PreconditionRequired"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/travel-requests/{id}/reject": {
      "post": {
        "operationId": "expense.travel_request.reject",
        "summary": "Reject a travel request",
        "description": "`status='REJECTED'` with a `decision_note` reason, shown on EXP-S07 (EXP-S11, db 08 §1.5 gap fix). Audited (`XC-F06`).",
        "tags": [
          "expense",
          "travel_request"
        ],
        "x-token": "expense.travel_request.reject",
        "x-realizes-features": [
          "EXP-F02"
        ],
        "x-screens": [
          "EXP-S11"
        ],
        "x-touches-entities": [
          "expense.travel_requests"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "expense.travel_request.rejected",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": "expense",
        "x-provisional": null,
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "name": "If-Match",
            "in": "header",
            "required": true,
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DecisionNoteInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Rejected.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "Idempotency-Replayed": {
                "$ref": "#/components/headers/IdempotencyReplayed"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRequest"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "428": {
            "$ref": "#/components/responses/PreconditionRequired"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/travel-advances": {
      "post": {
        "operationId": "expense.travel_advance.create",
        "summary": "Request a cash advance against an approved trip",
        "description": "EXP-S08 **Submit Request** — creates `expense.travel_advances` (`REQUESTED`) against a `travel_request` with `status='APPROVED'`. **Maker-checker on issue** (db 08 §1.3 check `submitted_by <> approved_by`) — routed to a different approver via the inbox (`XC-F12`); the checker's approve rejects with 409 `MAKER_EQUALS_CHECKER` if the same principal both raised and would approve it. Distinct from a salary advance (`PAY-F06`) — this is **trip funding**.\n",
        "tags": [
          "expense",
          "travel_advance"
        ],
        "x-token": "expense.travel_advance.create",
        "x-realizes-features": [
          "EXP-F03"
        ],
        "x-screens": [
          "EXP-S08"
        ],
        "x-touches-entities": [
          "expense.travel_advances",
          "expense.travel_requests",
          "people.employees"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "expense.travel_advance.requested",
        "x-rls-scope": "self",
        "x-append-only": false,
        "x-entitlement": "expense",
        "x-provisional": null,
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TravelAdvanceCreate"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Advance requested, `REQUESTED`, routed to the checker.",
            "headers": {
              "Location": {
                "$ref": "#/components/headers/Location"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "Idempotency-Replayed": {
                "$ref": "#/components/headers/IdempotencyReplayed"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelAdvance"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/travel-advances/{id}": {
      "get": {
        "operationId": "expense.travel_advance.get",
        "summary": "Get one travel advance",
        "description": "The advance's requested/approved/disbursed amounts and settlement state (embedded on EXP-S07; read directly ahead of EXP-S09 settlement).",
        "tags": [
          "expense",
          "travel_advance"
        ],
        "x-token": "expense.travel_advance.get",
        "x-realizes-features": [
          "EXP-F03"
        ],
        "x-screens": [
          "EXP-S07",
          "EXP-S09"
        ],
        "x-touches-entities": [
          "expense.travel_advances"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "self",
        "x-append-only": false,
        "x-entitlement": "expense",
        "x-provisional": null,
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          }
        ],
        "responses": {
          "200": {
            "description": "The travel advance.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelAdvance"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/travel-advances/admin": {
      "get": {
        "operationId": "expense.travel_advance.list_admin",
        "summary": "Finance's advance issue & settlement queue",
        "description": "Requested / disbursed / pending-settlement / settled tabs (EXP-S12).",
        "tags": [
          "expense",
          "travel_advance"
        ],
        "x-token": "expense.travel_advance.list_admin",
        "x-realizes-features": [
          "EXP-F03"
        ],
        "x-screens": [
          "EXP-S12"
        ],
        "x-touches-entities": [
          "expense.travel_advances"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": "expense",
        "x-provisional": null,
        "parameters": [
          {
            "name": "employee_id",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/UuidRef"
            }
          },
          {
            "name": "travel_request_id",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/UuidRef"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/TravelAdvanceStatus"
            }
          },
          {
            "$ref": "#/components/parameters/PageSize"
          },
          {
            "$ref": "#/components/parameters/PageAfter"
          },
          {
            "$ref": "#/components/parameters/PageBefore"
          },
          {
            "name": "sort",
            "in": "query",
            "required": false,
            "description": "Sort whitelist: `created_at`, `-created_at`, `status`, `employee_id`.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Tenant-wide page of travel advances.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelAdvancePage"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/travel-advances/{id}/approve": {
      "post": {
        "operationId": "expense.travel_advance.approve",
        "summary": "Approve (sanction) a travel advance — checker step",
        "description": "`REQUESTED → APPROVED`, sets `approved_amount`/`approved_by`/`approved_at`. **Four-eyes enforced** (db 08 §1.3 check `submitted_by <> approved_by`) — 409 `MAKER_EQUALS_CHECKER` when the caller is also the maker (EXP-S12). Audited (`XC-F06`).\n",
        "tags": [
          "expense",
          "travel_advance"
        ],
        "x-token": "expense.travel_advance.approve",
        "x-realizes-features": [
          "EXP-F03"
        ],
        "x-screens": [
          "EXP-S12"
        ],
        "x-touches-entities": [
          "expense.travel_advances"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "expense.travel_advance.approved",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": "expense",
        "x-provisional": null,
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "name": "If-Match",
            "in": "header",
            "required": true,
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TravelAdvanceApprovalInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Approved.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "Idempotency-Replayed": {
                "$ref": "#/components/headers/IdempotencyReplayed"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelAdvance"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "428": {
            "$ref": "#/components/responses/PreconditionRequired"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/travel-advances/{id}/reject": {
      "post": {
        "operationId": "expense.travel_advance.reject",
        "summary": "Reject a travel advance request",
        "description": "`status='REJECTED'` with a `decision_note` reason (EXP-S12, db 08 §1.5 gap fix). Audited (`XC-F06`).",
        "tags": [
          "expense",
          "travel_advance"
        ],
        "x-token": "expense.travel_advance.reject",
        "x-realizes-features": [
          "EXP-F03"
        ],
        "x-screens": [
          "EXP-S12"
        ],
        "x-touches-entities": [
          "expense.travel_advances"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "expense.travel_advance.rejected",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": "expense",
        "x-provisional": null,
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "name": "If-Match",
            "in": "header",
            "required": true,
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DecisionNoteInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Rejected.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "Idempotency-Replayed": {
                "$ref": "#/components/headers/IdempotencyReplayed"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelAdvance"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "428": {
            "$ref": "#/components/responses/PreconditionRequired"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/travel-advances/{id}/disburse": {
      "post": {
        "operationId": "expense.travel_advance.disburse",
        "summary": "Disburse a sanctioned travel advance",
        "description": "`APPROVED → DISBURSED`, sets `disbursed_amount`/`disbursed_at` — the cash is paid out (EXP-S12).",
        "tags": [
          "expense",
          "travel_advance"
        ],
        "x-token": "expense.travel_advance.disburse",
        "x-realizes-features": [
          "EXP-F03"
        ],
        "x-screens": [
          "EXP-S12"
        ],
        "x-touches-entities": [
          "expense.travel_advances"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "async",
        "x-emits-event": "expense.travel_advance.disbursed",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": "expense",
        "x-provisional": null,
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "name": "If-Match",
            "in": "header",
            "required": true,
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TravelAdvanceDisburseInput"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Accepted — `DISBURSED`; payout confirmation is async.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "Idempotency-Replayed": {
                "$ref": "#/components/headers/IdempotencyReplayed"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelAdvance"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "428": {
            "$ref": "#/components/responses/PreconditionRequired"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/travel-advances/{id}/settle": {
      "post": {
        "operationId": "expense.travel_advance.settle",
        "summary": "Reconcile a disbursed advance against its settlement claim",
        "description": "Finance's EXP-S12 **Settle** — reconciles `settled_amount`/`balance_amount` against the linked `ADVANCE_SETTLEMENT` `expense_claim` (filed by the employee on EXP-S09 and already `APPROVED`) and moves `PENDING_SETTLEMENT → SETTLED` (`balance_amount > 0`, unspent, recovered from the employee via payroll deduction) or `RECOVERED` (`balance_amount < 0`, overspend, additional reimbursement due via payroll earning); the net is routed to payroll (PAY-F04) asynchronously. 422 when the advance has no `APPROVED` settlement claim yet.\n",
        "tags": [
          "expense",
          "travel_advance"
        ],
        "x-token": "expense.travel_advance.settle",
        "x-realizes-features": [
          "EXP-F03"
        ],
        "x-screens": [
          "EXP-S09",
          "EXP-S12"
        ],
        "x-touches-entities": [
          "expense.travel_advances",
          "expense.expense_claims"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "async",
        "x-emits-event": "expense.travel_advance.settled",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": "expense",
        "x-provisional": null,
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "name": "If-Match",
            "in": "header",
            "required": true,
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DecisionNoteInput"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Accepted — reconciled to `SETTLED`/`RECOVERED`; payroll net routing is async.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "Idempotency-Replayed": {
                "$ref": "#/components/headers/IdempotencyReplayed"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelAdvance"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "428": {
            "$ref": "#/components/responses/PreconditionRequired"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/expense-policies": {
      "get": {
        "operationId": "expense.expense_policy.list",
        "summary": "List expense-policy bands (config)",
        "description": "The category-cap / grade-location policy bands the submit-time engine evaluates against (EXP-S13).",
        "tags": [
          "expense",
          "expense_policy"
        ],
        "x-token": "expense.expense_policy.list",
        "x-realizes-features": [
          "EXP-F04"
        ],
        "x-screens": [
          "EXP-S13"
        ],
        "x-touches-entities": [
          "expense.expense_policies"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": "expense",
        "x-provisional": null,
        "parameters": [
          {
            "name": "legal_entity_id",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/UuidRef"
            }
          },
          {
            "name": "grade_id",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/UuidRef"
            }
          },
          {
            "name": "work_location_id",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/UuidRef"
            }
          },
          {
            "name": "category",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/ExpenseCategory"
            }
          },
          {
            "name": "is_active",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean"
            }
          },
          {
            "$ref": "#/components/parameters/PageSize"
          },
          {
            "$ref": "#/components/parameters/PageAfter"
          },
          {
            "$ref": "#/components/parameters/PageBefore"
          },
          {
            "name": "sort",
            "in": "query",
            "required": false,
            "description": "Sort whitelist: `policy_code`, `effective_from`.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Page of policy bands.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExpensePolicyPage"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "post": {
        "operationId": "expense.expense_policy.create",
        "summary": "Add a new effective-dated policy version",
        "description": "An edit is **always a new `version_no` row**, never an in-place change (EXP-S13) — the applied version stays stamped on historical claims' `policy_snapshot`. Audited (`XC-F06`).\n\n`version_no` is **derived server-side** (`max(version_no) + 1` over the tenant's rows for this `policy_code`, or `1` for a code seen for the first time) and is therefore absent from the request body: a client cannot pin, skip or rewrite a version number.\n\nIf the code's newest version is still **open-ended** (`effective_to: null`) and starts strictly before the new `effective_from`, its window is CLOSED to `effective_from - 1 day`. That is the only write this operation makes to an existing row, and it only ever moves an open end forward — for every date before the new version opens, the predecessor still resolves, so no already evaluable date changes its answer.\n\nAny OTHER intersection with an existing version is refused with `422 VALIDATION_FAILED` (`pointer: /effective_from`, `rule: cross-field`) rather than reconciled — the FSD's *overlapping effective dates* form error. A version starting on the same day as the open predecessor is refused the same way, because closing it would move a window backwards. `cap_period` is required whenever `cap_amount` is set (`pointer: /cap_period`), and a money object's `currency_code` must equal the band's own `currency_code` — the row carries one currency column, so a cap quoted in a second currency has nowhere to be stored.\n",
        "tags": [
          "expense",
          "expense_policy"
        ],
        "x-token": "expense.expense_policy.create",
        "x-realizes-features": [
          "EXP-F04"
        ],
        "x-screens": [
          "EXP-S13"
        ],
        "x-touches-entities": [
          "expense.expense_policies"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": "expense",
        "x-provisional": null,
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ExpensePolicyCreate"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Policy version created.",
            "headers": {
              "Location": {
                "$ref": "#/components/headers/Location"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "Idempotency-Replayed": {
                "$ref": "#/components/headers/IdempotencyReplayed"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExpensePolicy"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/per-diem-rates": {
      "get": {
        "operationId": "expense.per_diem_rate.list",
        "summary": "List per-diem rates (config)",
        "description": "Effective-dated daily allowances by location/grade/category the travel/claim engine applies (EXP-S13).",
        "tags": [
          "expense",
          "per_diem_rate"
        ],
        "x-token": "expense.per_diem_rate.list",
        "x-realizes-features": [
          "EXP-F04"
        ],
        "x-screens": [
          "EXP-S13"
        ],
        "x-touches-entities": [
          "expense.per_diem_rates"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": "expense",
        "x-provisional": null,
        "parameters": [
          {
            "name": "legal_entity_id",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/UuidRef"
            }
          },
          {
            "name": "work_location_id",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/UuidRef"
            }
          },
          {
            "name": "category",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/PerDiemCategory"
            }
          },
          {
            "name": "is_active",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean"
            }
          },
          {
            "$ref": "#/components/parameters/PageSize"
          },
          {
            "$ref": "#/components/parameters/PageAfter"
          },
          {
            "$ref": "#/components/parameters/PageBefore"
          },
          {
            "name": "sort",
            "in": "query",
            "required": false,
            "description": "Sort whitelist: `effective_from`, `category`.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Page of per-diem rates.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PerDiemRatePage"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "post": {
        "operationId": "expense.per_diem_rate.create",
        "summary": "Add a new effective-dated per-diem rate",
        "description": "A new rate is always a new row with its own `effective_from` (EXP-S13) — a past trip resolves the rate in force at travel time. Audited (`XC-F06`).\n\n`per_diem_rates` has **no `version_no` and no code**: a rate's identity is its BAND (`legal_entity_id` + `work_location_id` + `grade_id` + `category`, the tuple `per_diem_rates_tenant_band_key` makes unique) and a new version IS a row with a later `effective_from`. The band's currently open row is closed to `effective_from - 1 day`, forward only, exactly as `expense.expense_policy.create` closes a policy version; any other overlap in the same band is a `422` on `/effective_from`. `work_location_id`/`grade_id` are nullable band keys matched with `IS NOT DISTINCT FROM`, so \"all locations\" is its own timeline rather than a wildcard over the specific ones. `location_label` is **not** part of the band key, so two rows differing only by label collide — that collision answers `409`, never `500`.\n",
        "tags": [
          "expense",
          "per_diem_rate"
        ],
        "x-token": "expense.per_diem_rate.create",
        "x-realizes-features": [
          "EXP-F04"
        ],
        "x-screens": [
          "EXP-S13"
        ],
        "x-touches-entities": [
          "expense.per_diem_rates"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": "expense",
        "x-provisional": null,
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PerDiemRateCreate"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Per-diem rate created.",
            "headers": {
              "Location": {
                "$ref": "#/components/headers/Location"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "Idempotency-Replayed": {
                "$ref": "#/components/headers/IdempotencyReplayed"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PerDiemRate"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/benefit-plans": {
      "get": {
        "operationId": "benefits.benefit_plan.list",
        "summary": "List benefit plans",
        "description": "Pack-driven plans (GMC/GPA/GTL/FBP/…) an employee browses for enrolment (BEN-S01/S02) or HR administers (BEN-S06).",
        "tags": [
          "benefits",
          "benefit_plan"
        ],
        "x-token": "benefits.benefit_plan.list",
        "x-realizes-features": [
          "BEN-F01",
          "BEN-F02"
        ],
        "x-screens": [
          "BEN-S01",
          "BEN-S02",
          "BEN-S06"
        ],
        "x-touches-entities": [
          "benefits.benefit_plans"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": "benefits",
        "x-provisional": null,
        "parameters": [
          {
            "name": "plan_type",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/BenefitPlanType"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/BenefitPlanStatus"
            }
          },
          {
            "name": "legal_entity_id",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/UuidRef"
            }
          },
          {
            "$ref": "#/components/parameters/PageSize"
          },
          {
            "$ref": "#/components/parameters/PageAfter"
          },
          {
            "$ref": "#/components/parameters/PageBefore"
          },
          {
            "name": "sort",
            "in": "query",
            "required": false,
            "description": "Sort whitelist: `plan_code`, `status`, `policy_end_date`.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Page of benefit plans.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BenefitPlanPage"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "post": {
        "operationId": "benefits.benefit_plan.create",
        "summary": "Configure a benefit plan",
        "description": "BEN-S06 (or, for `plan_type='FLEXIBLE_FBP'`, the BEN-S07 FBP plan config) — the entity's compliance-pack version is stamped (`pack_version`, db 08 §2.1). Audited (`XC-F06`).\n",
        "tags": [
          "benefits",
          "benefit_plan"
        ],
        "x-token": "benefits.benefit_plan.create",
        "x-realizes-features": [
          "BEN-F01",
          "BEN-F02"
        ],
        "x-screens": [
          "BEN-S06",
          "BEN-S07"
        ],
        "x-touches-entities": [
          "benefits.benefit_plans"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": "benefits",
        "x-provisional": null,
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BenefitPlanCreate"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Plan created, `DRAFT`.",
            "headers": {
              "Location": {
                "$ref": "#/components/headers/Location"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "Idempotency-Replayed": {
                "$ref": "#/components/headers/IdempotencyReplayed"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BenefitPlan"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/benefit-plans/{id}": {
      "get": {
        "operationId": "benefits.benefit_plan.get",
        "summary": "Get one benefit plan",
        "description": "Plan detail — coverage envelope, eligibility, and the enrolment/policy window (BEN-S01, BEN-S06).",
        "tags": [
          "benefits",
          "benefit_plan"
        ],
        "x-token": "benefits.benefit_plan.get",
        "x-realizes-features": [
          "BEN-F01",
          "BEN-F02"
        ],
        "x-screens": [
          "BEN-S01",
          "BEN-S02",
          "BEN-S06",
          "BEN-S07"
        ],
        "x-touches-entities": [
          "benefits.benefit_plans"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": "benefits",
        "x-provisional": null,
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          }
        ],
        "responses": {
          "200": {
            "description": "The benefit plan.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BenefitPlan"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "patch": {
        "operationId": "benefits.benefit_plan.update",
        "summary": "Update a benefit plan (status, window, coverage)",
        "description": "Edits plan config or advances its lifecycle (`DRAFT → ACTIVE → RENEWING → EXPIRED/WITHDRAWN`, BEN-S06/BEN-S07). Audited (`XC-F06`).",
        "tags": [
          "benefits",
          "benefit_plan"
        ],
        "x-token": "benefits.benefit_plan.update",
        "x-realizes-features": [
          "BEN-F01",
          "BEN-F02"
        ],
        "x-screens": [
          "BEN-S06",
          "BEN-S07"
        ],
        "x-touches-entities": [
          "benefits.benefit_plans"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": "benefits",
        "x-provisional": null,
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "name": "If-Match",
            "in": "header",
            "required": true,
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BenefitPlanUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated plan.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "Idempotency-Replayed": {
                "$ref": "#/components/headers/IdempotencyReplayed"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BenefitPlan"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "428": {
            "$ref": "#/components/responses/PreconditionRequired"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/benefit-enrolments": {
      "post": {
        "operationId": "benefits.benefit_enrolment.create",
        "summary": "Enrol in a benefit plan",
        "description": "BEN-S02 **Confirm Enrolment** — creates `benefits.benefit_enrolments` (`PENDING → ENROLLED`), stamping `plan_pack_version`; on confirm an `insurance_records` row is issued per covered member (e-card, `XC-F07`) by the jobs tier (`XC-F08`), so this operation is **async**. Only permitted while the plan's `enrolment_window_start..end` is open, or one live enrolment per employee per plan already exists (db 08 §2.1 unique constraint).\n",
        "tags": [
          "benefits",
          "benefit_enrolment"
        ],
        "x-token": "benefits.benefit_enrolment.create",
        "x-realizes-features": [
          "BEN-F01"
        ],
        "x-screens": [
          "BEN-S02"
        ],
        "x-touches-entities": [
          "benefits.benefit_enrolments",
          "benefits.benefit_plans",
          "people.employees",
          "people.dependents"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "async",
        "x-emits-event": "benefits.benefit_enrolment.enrolled",
        "x-rls-scope": "self",
        "x-append-only": false,
        "x-entitlement": "benefits",
        "x-provisional": null,
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BenefitEnrolmentCreate"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Accepted — `PENDING`/`ENROLLED`; per-member e-card issuance runs async on the jobs tier.",
            "headers": {
              "Location": {
                "$ref": "#/components/headers/Location"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "Idempotency-Replayed": {
                "$ref": "#/components/headers/IdempotencyReplayed"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BenefitEnrolment"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "get": {
        "operationId": "benefits.benefit_enrolment.list",
        "summary": "My benefit enrolments",
        "description": "The employee's active plans and cover (BEN-S01 \"my benefits & cover\").",
        "tags": [
          "benefits",
          "benefit_enrolment"
        ],
        "x-token": "benefits.benefit_enrolment.list",
        "x-realizes-features": [
          "BEN-F01"
        ],
        "x-screens": [
          "BEN-S01"
        ],
        "x-touches-entities": [
          "benefits.benefit_enrolments"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "self",
        "x-append-only": false,
        "x-entitlement": "benefits",
        "x-provisional": null,
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/BenefitEnrolmentStatus"
            }
          },
          {
            "name": "benefit_plan_id",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/UuidRef"
            }
          },
          {
            "$ref": "#/components/parameters/PageSize"
          },
          {
            "$ref": "#/components/parameters/PageAfter"
          },
          {
            "$ref": "#/components/parameters/PageBefore"
          },
          {
            "name": "sort",
            "in": "query",
            "required": false,
            "description": "Sort whitelist: `effective_from`, `status`.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Page of the caller's own enrolments.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BenefitEnrolmentPage"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/benefit-enrolments/{id}": {
      "get": {
        "operationId": "benefits.benefit_enrolment.get",
        "summary": "Get one benefit enrolment",
        "description": "Cover tier, covered dependents, and status — the unit BEN-S03 dependents management and BEN-S04 e-cards attach to.",
        "tags": [
          "benefits",
          "benefit_enrolment"
        ],
        "x-token": "benefits.benefit_enrolment.get",
        "x-realizes-features": [
          "BEN-F01"
        ],
        "x-screens": [
          "BEN-S01",
          "BEN-S03"
        ],
        "x-touches-entities": [
          "benefits.benefit_enrolments",
          "people.dependents"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "self",
        "x-append-only": false,
        "x-entitlement": "benefits",
        "x-provisional": null,
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          }
        ],
        "responses": {
          "200": {
            "description": "The enrolment.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BenefitEnrolment"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "patch": {
        "operationId": "benefits.benefit_enrolment.update",
        "summary": "Update covered dependents / coverage tier",
        "description": "BEN-S03 dependent toggle — updates `covered_dependents[]` within `dependent_policy`; permitted only during the plan's enrolment window or on a qualifying life event (marriage/newborn), read-only otherwise. Issues/withdraws the affected member's `insurance_records` e-card asynchronously.\n",
        "tags": [
          "benefits",
          "benefit_enrolment"
        ],
        "x-token": "benefits.benefit_enrolment.update",
        "x-realizes-features": [
          "BEN-F01"
        ],
        "x-screens": [
          "BEN-S03"
        ],
        "x-touches-entities": [
          "benefits.benefit_enrolments",
          "people.dependents"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "async",
        "x-emits-event": "benefits.benefit_enrolment.dependents_updated",
        "x-rls-scope": "self",
        "x-append-only": false,
        "x-entitlement": "benefits",
        "x-provisional": null,
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "name": "If-Match",
            "in": "header",
            "required": true,
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BenefitEnrolmentUpdate"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Accepted — dependent cover updated; e-card issue/withdraw runs async on the jobs tier.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "Idempotency-Replayed": {
                "$ref": "#/components/headers/IdempotencyReplayed"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BenefitEnrolment"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "428": {
            "$ref": "#/components/responses/PreconditionRequired"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/benefit-enrolments/{id}/waive": {
      "post": {
        "operationId": "benefits.benefit_enrolment.waive",
        "summary": "Waive a pending enrolment",
        "description": "`PENDING → WAIVED` — the employee opts out (BEN-S02).",
        "tags": [
          "benefits",
          "benefit_enrolment"
        ],
        "x-token": "benefits.benefit_enrolment.waive",
        "x-realizes-features": [
          "BEN-F01"
        ],
        "x-screens": [
          "BEN-S02"
        ],
        "x-touches-entities": [
          "benefits.benefit_enrolments"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "benefits.benefit_enrolment.waived",
        "x-rls-scope": "self",
        "x-append-only": false,
        "x-entitlement": "benefits",
        "x-provisional": null,
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "name": "If-Match",
            "in": "header",
            "required": true,
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DecisionNoteInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Waived.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "Idempotency-Replayed": {
                "$ref": "#/components/headers/IdempotencyReplayed"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BenefitEnrolment"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "428": {
            "$ref": "#/components/responses/PreconditionRequired"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/benefit-enrolments/admin": {
      "get": {
        "operationId": "benefits.benefit_enrolment.list_admin",
        "summary": "HR's tenant-wide enrolment register",
        "description": "The per-employee enrolment register HR administers alongside plans and insurance records (BEN-S06).",
        "tags": [
          "benefits",
          "benefit_enrolment"
        ],
        "x-token": "benefits.benefit_enrolment.list_admin",
        "x-realizes-features": [
          "BEN-F01"
        ],
        "x-screens": [
          "BEN-S06"
        ],
        "x-touches-entities": [
          "benefits.benefit_enrolments"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": "benefits",
        "x-provisional": null,
        "parameters": [
          {
            "name": "employee_id",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/UuidRef"
            }
          },
          {
            "name": "benefit_plan_id",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/UuidRef"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/BenefitEnrolmentStatus"
            }
          },
          {
            "$ref": "#/components/parameters/PageSize"
          },
          {
            "$ref": "#/components/parameters/PageAfter"
          },
          {
            "$ref": "#/components/parameters/PageBefore"
          },
          {
            "name": "sort",
            "in": "query",
            "required": false,
            "description": "Sort whitelist: `enrolment_no`, `status`.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Tenant-wide page of enrolments.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BenefitEnrolmentPage"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/insurance-records": {
      "get": {
        "operationId": "benefits.insurance_record.list",
        "summary": "My insurance e-cards",
        "description": "One card per insured member the employee (or their covered dependents) holds (BEN-S04 member switcher).",
        "tags": [
          "benefits",
          "insurance_record"
        ],
        "x-token": "benefits.insurance_record.list",
        "x-realizes-features": [
          "BEN-F01"
        ],
        "x-screens": [
          "BEN-S04"
        ],
        "x-touches-entities": [
          "benefits.insurance_records"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "self",
        "x-append-only": false,
        "x-entitlement": "benefits",
        "x-provisional": null,
        "parameters": [
          {
            "name": "benefit_enrolment_id",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/UuidRef"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/InsuranceRecordStatus"
            }
          },
          {
            "$ref": "#/components/parameters/PageSize"
          },
          {
            "$ref": "#/components/parameters/PageAfter"
          },
          {
            "$ref": "#/components/parameters/PageBefore"
          },
          {
            "name": "sort",
            "in": "query",
            "required": false,
            "description": "Sort whitelist: `expiry_date`, `status`.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Page of the caller's own (and covered dependents') insurance records.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InsuranceRecordPage"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "post": {
        "operationId": "benefits.insurance_record.create",
        "summary": "Issue a per-member insurance record / e-card",
        "description": "HR's manual issue of a member's card (BEN-S06) — one row per insured member so each card and expiry track independently (db 08 §2.1).",
        "tags": [
          "benefits",
          "insurance_record"
        ],
        "x-token": "benefits.insurance_record.create",
        "x-realizes-features": [
          "BEN-F01"
        ],
        "x-screens": [
          "BEN-S06"
        ],
        "x-touches-entities": [
          "benefits.insurance_records",
          "benefits.benefit_enrolments",
          "people.dependents"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": "benefits.insurance_record.issued",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": "benefits",
        "x-provisional": null,
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InsuranceRecordCreate"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Insurance record issued.",
            "headers": {
              "Location": {
                "$ref": "#/components/headers/Location"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "Idempotency-Replayed": {
                "$ref": "#/components/headers/IdempotencyReplayed"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InsuranceRecord"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/insurance-records/{id}": {
      "get": {
        "operationId": "benefits.insurance_record.get",
        "summary": "Get one insurance e-card",
        "description": "Member card detail with the presigned e-card download (BEN-S04).",
        "tags": [
          "benefits",
          "insurance_record"
        ],
        "x-token": "benefits.insurance_record.get",
        "x-realizes-features": [
          "BEN-F01"
        ],
        "x-screens": [
          "BEN-S04"
        ],
        "x-touches-entities": [
          "benefits.insurance_records"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "self",
        "x-append-only": false,
        "x-entitlement": "benefits",
        "x-provisional": null,
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          }
        ],
        "responses": {
          "200": {
            "description": "The insurance record, with a time-limited presigned e-card URL where issued.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InsuranceRecord"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "patch": {
        "operationId": "benefits.insurance_record.update",
        "summary": "Update an insurance record (re-issue card, change status)",
        "description": "Corrects member details, re-issues the e-card file, or transitions status (`ACTIVE`/`EXPIRED`/`SUSPENDED`/`CANCELLED`, BEN-S06). Audited (`XC-F06`).",
        "tags": [
          "benefits",
          "insurance_record"
        ],
        "x-token": "benefits.insurance_record.update",
        "x-realizes-features": [
          "BEN-F01"
        ],
        "x-screens": [
          "BEN-S06"
        ],
        "x-touches-entities": [
          "benefits.insurance_records"
        ],
        "x-idempotent": true,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": "benefits",
        "x-provisional": null,
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "name": "If-Match",
            "in": "header",
            "required": true,
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InsuranceRecordUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated insurance record.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "Idempotency-Replayed": {
                "$ref": "#/components/headers/IdempotencyReplayed"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InsuranceRecord"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "428": {
            "$ref": "#/components/responses/PreconditionRequired"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/insurance-records/admin": {
      "get": {
        "operationId": "benefits.insurance_record.list_admin",
        "summary": "HR's insurance-records register",
        "description": "Every insured member's card, validity, and status across the workforce, including the expiry/renewal scan surface (BEN-S06).",
        "tags": [
          "benefits",
          "insurance_record"
        ],
        "x-token": "benefits.insurance_record.list_admin",
        "x-realizes-features": [
          "BEN-F01"
        ],
        "x-screens": [
          "BEN-S06"
        ],
        "x-touches-entities": [
          "benefits.insurance_records"
        ],
        "x-idempotent": false,
        "x-market": "both",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": "benefits",
        "x-provisional": null,
        "parameters": [
          {
            "name": "benefit_plan_id",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/UuidRef"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/InsuranceRecordStatus"
            }
          },
          {
            "name": "expiry_date[to]",
            "in": "query",
            "required": false,
            "description": "Upper bound on `expiry_date` — the expiry/renewal scan filter (`XC-F08`).",
            "schema": {
              "$ref": "#/components/schemas/DateOnlyRef"
            }
          },
          {
            "$ref": "#/components/parameters/PageSize"
          },
          {
            "$ref": "#/components/parameters/PageAfter"
          },
          {
            "$ref": "#/components/parameters/PageBefore"
          },
          {
            "name": "sort",
            "in": "query",
            "required": false,
            "description": "Sort whitelist: `expiry_date`, `status`.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Tenant-wide page of insurance records.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InsuranceRecordPage"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/fbp-declarations": {
      "post": {
        "operationId": "benefits.fbp_declaration.create",
        "summary": "Submit an FBP declaration",
        "description": "BEN-S05 **Submit Declaration** — creates `benefits.fbp_declarations` against the `FLEXIBLE_FBP` plan (`DRAFT → DECLARED → SUBMITTED`), **validated synchronously** against the plan's per-component caps (`allocated_amount ≤ total_pot_amount`, db 08 §2.2 check) within `window_start..end`. One live declaration per employee per plan per fiscal year (unique constraint). **India-centric tax treatment** — modelled `Both` via the pack, but a KSA `FLEXIBLE_FBP` plan carries no tax exemption (no `TAX-F02` feed).\n",
        "tags": [
          "benefits",
          "fbp_declaration"
        ],
        "x-token": "benefits.fbp_declaration.create",
        "x-realizes-features": [
          "BEN-F02"
        ],
        "x-screens": [
          "BEN-S05"
        ],
        "x-touches-entities": [
          "benefits.fbp_declarations",
          "benefits.benefit_plans",
          "people.employees"
        ],
        "x-idempotent": true,
        "x-market": "India",
        "x-sync-async": "sync",
        "x-emits-event": "benefits.fbp_declaration.submitted",
        "x-rls-scope": "self",
        "x-append-only": false,
        "x-entitlement": "benefits",
        "x-provisional": null,
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FbpDeclarationCreate"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Declaration submitted, `SUBMITTED`, pending Finance/HR verification.",
            "headers": {
              "Location": {
                "$ref": "#/components/headers/Location"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "Idempotency-Replayed": {
                "$ref": "#/components/headers/IdempotencyReplayed"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FbpDeclaration"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "get": {
        "operationId": "benefits.fbp_declaration.list",
        "summary": "My FBP declarations",
        "description": "The employee's declarations by fiscal year and status (BEN-S05).",
        "tags": [
          "benefits",
          "fbp_declaration"
        ],
        "x-token": "benefits.fbp_declaration.list",
        "x-realizes-features": [
          "BEN-F02"
        ],
        "x-screens": [
          "BEN-S05"
        ],
        "x-touches-entities": [
          "benefits.fbp_declarations"
        ],
        "x-idempotent": false,
        "x-market": "India",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "self",
        "x-append-only": false,
        "x-entitlement": "benefits",
        "x-provisional": null,
        "parameters": [
          {
            "name": "fiscal_year",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/FbpDeclarationStatus"
            }
          },
          {
            "$ref": "#/components/parameters/PageSize"
          },
          {
            "$ref": "#/components/parameters/PageAfter"
          },
          {
            "$ref": "#/components/parameters/PageBefore"
          },
          {
            "name": "sort",
            "in": "query",
            "required": false,
            "description": "Sort whitelist: `fiscal_year`, `-fiscal_year`, `status`.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Page of the caller's own declarations.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FbpDeclarationPage"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/fbp-declarations/{id}": {
      "get": {
        "operationId": "benefits.fbp_declaration.get",
        "summary": "Get one FBP declaration",
        "description": "The declaration with its per-component allocation lines (BEN-S05, BEN-S07 verify drawer).",
        "tags": [
          "benefits",
          "fbp_declaration"
        ],
        "x-token": "benefits.fbp_declaration.get",
        "x-realizes-features": [
          "BEN-F02"
        ],
        "x-screens": [
          "BEN-S05",
          "BEN-S07"
        ],
        "x-touches-entities": [
          "benefits.fbp_declarations"
        ],
        "x-idempotent": false,
        "x-market": "India",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "self",
        "x-append-only": false,
        "x-entitlement": "benefits",
        "x-provisional": null,
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          }
        ],
        "responses": {
          "200": {
            "description": "The FBP declaration.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FbpDeclaration"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      },
      "patch": {
        "operationId": "benefits.fbp_declaration.update",
        "summary": "Edit and resubmit an FBP declaration",
        "description": "Edits allocation lines on a `DRAFT` or verifier-`REJECTED` declaration and resubmits (BEN-S05); re-validated synchronously against caps.",
        "tags": [
          "benefits",
          "fbp_declaration"
        ],
        "x-token": "benefits.fbp_declaration.update",
        "x-realizes-features": [
          "BEN-F02"
        ],
        "x-screens": [
          "BEN-S05"
        ],
        "x-touches-entities": [
          "benefits.fbp_declarations",
          "benefits.benefit_plans"
        ],
        "x-idempotent": true,
        "x-market": "India",
        "x-sync-async": "sync",
        "x-emits-event": "benefits.fbp_declaration.submitted",
        "x-rls-scope": "self",
        "x-append-only": false,
        "x-entitlement": "benefits",
        "x-provisional": null,
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "name": "If-Match",
            "in": "header",
            "required": true,
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FbpDeclarationUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated (and resubmitted) declaration.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "Idempotency-Replayed": {
                "$ref": "#/components/headers/IdempotencyReplayed"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FbpDeclaration"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "428": {
            "$ref": "#/components/responses/PreconditionRequired"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/fbp-declarations/admin": {
      "get": {
        "operationId": "benefits.fbp_declaration.list_admin",
        "summary": "Finance/HR's FBP verification queue",
        "description": "Declarations by employee/FY/status awaiting verification before payroll consumes them (BEN-S07).",
        "tags": [
          "benefits",
          "fbp_declaration"
        ],
        "x-token": "benefits.fbp_declaration.list_admin",
        "x-realizes-features": [
          "BEN-F02"
        ],
        "x-screens": [
          "BEN-S07"
        ],
        "x-touches-entities": [
          "benefits.fbp_declarations"
        ],
        "x-idempotent": false,
        "x-market": "India",
        "x-sync-async": "sync",
        "x-emits-event": null,
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": "benefits",
        "x-provisional": null,
        "parameters": [
          {
            "name": "employee_id",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/UuidRef"
            }
          },
          {
            "name": "fiscal_year",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/FbpDeclarationStatus"
            }
          },
          {
            "$ref": "#/components/parameters/PageSize"
          },
          {
            "$ref": "#/components/parameters/PageAfter"
          },
          {
            "$ref": "#/components/parameters/PageBefore"
          },
          {
            "name": "sort",
            "in": "query",
            "required": false,
            "description": "Sort whitelist: `fiscal_year`, `status`, `employee_id`.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Tenant-wide page of declarations.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FbpDeclarationPage"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/fbp-declarations/{id}/verify": {
      "post": {
        "operationId": "benefits.fbp_declaration.verify",
        "summary": "Verify an FBP declaration",
        "description": "`status='VERIFIED'`, sets `verified_by` — a declaration over its caps cannot be verified (422). BEN-S07. Audited (`XC-F06`).",
        "tags": [
          "benefits",
          "fbp_declaration"
        ],
        "x-token": "benefits.fbp_declaration.verify",
        "x-realizes-features": [
          "BEN-F02"
        ],
        "x-screens": [
          "BEN-S07"
        ],
        "x-touches-entities": [
          "benefits.fbp_declarations"
        ],
        "x-idempotent": true,
        "x-market": "India",
        "x-sync-async": "sync",
        "x-emits-event": "benefits.fbp_declaration.verified",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": "benefits",
        "x-provisional": null,
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "name": "If-Match",
            "in": "header",
            "required": true,
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DecisionNoteInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Verified.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "Idempotency-Replayed": {
                "$ref": "#/components/headers/IdempotencyReplayed"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FbpDeclaration"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "428": {
            "$ref": "#/components/responses/PreconditionRequired"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/fbp-declarations/{id}/reject": {
      "post": {
        "operationId": "benefits.fbp_declaration.reject",
        "summary": "Reject an FBP declaration back to draft",
        "description": "`status='REJECTED'` with a `decision_note` reason, back to `DRAFT` for correction (BEN-S07, db 08 §1.5 gap fix). Audited (`XC-F06`).",
        "tags": [
          "benefits",
          "fbp_declaration"
        ],
        "x-token": "benefits.fbp_declaration.reject",
        "x-realizes-features": [
          "BEN-F02"
        ],
        "x-screens": [
          "BEN-S07"
        ],
        "x-touches-entities": [
          "benefits.fbp_declarations"
        ],
        "x-idempotent": true,
        "x-market": "India",
        "x-sync-async": "sync",
        "x-emits-event": "benefits.fbp_declaration.rejected",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": "benefits",
        "x-provisional": null,
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "name": "If-Match",
            "in": "header",
            "required": true,
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DecisionNoteInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Rejected, back to `DRAFT`.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "Idempotency-Replayed": {
                "$ref": "#/components/headers/IdempotencyReplayed"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FbpDeclaration"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "428": {
            "$ref": "#/components/responses/PreconditionRequired"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    },
    "/fbp-declarations/{id}/lock": {
      "post": {
        "operationId": "benefits.fbp_declaration.lock",
        "summary": "Lock a verified FBP declaration for payroll consumption",
        "description": "`VERIFIED → LOCKED`, sets `locked_at` — the declaration becomes an immutable payroll input; the allocations are emitted to payroll (PAY-F04) and the **India** tax-exempt portions to investment tax (TAX-F02) asynchronously (BEN-S07). A KSA `FLEXIBLE_FBP` locks to pay components only, no tax feed (fsd 07 §Market variants). Audited (`XC-F06`).\n",
        "tags": [
          "benefits",
          "fbp_declaration"
        ],
        "x-token": "benefits.fbp_declaration.lock",
        "x-realizes-features": [
          "BEN-F02"
        ],
        "x-screens": [
          "BEN-S07"
        ],
        "x-touches-entities": [
          "benefits.fbp_declarations"
        ],
        "x-idempotent": true,
        "x-market": "India",
        "x-sync-async": "async",
        "x-emits-event": "benefits.fbp_declaration.locked",
        "x-rls-scope": "tenant",
        "x-append-only": false,
        "x-entitlement": "benefits",
        "x-provisional": null,
        "parameters": [
          {
            "$ref": "#/components/parameters/PathId"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "$ref": "#/components/parameters/IdempotencyKey"
          },
          {
            "name": "If-Match",
            "in": "header",
            "required": true,
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DecisionNoteInput"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Accepted — `LOCKED`; the payroll/tax feed is async.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              },
              "Idempotency-Replayed": {
                "$ref": "#/components/headers/IdempotencyReplayed"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FbpDeclaration"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "412": {
            "$ref": "#/components/responses/PreconditionFailed"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "423": {
            "$ref": "#/components/responses/Locked"
          },
          "428": {
            "$ref": "#/components/responses/PreconditionRequired"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerJWT": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT",
        "description": "Product session token. Two mint paths, one contract (ADR 0010): employees/managers authenticate against Keycloak (mobile + web); workspace staff arrive from the One portal via bridge-token SSO (`POST /api/sso/exchange` verifies the platform's Ed25519 token and mints the product session). The token carries IDENTITY ONLY — `sub`, `tenantUid`, `principal_class`, MFA level, session ref, `exp`. Roles/permissions are re-resolved server-side per request. Enforcement is layered: gateway (TLS/WAF/routing only — NEVER trusted for auth) → NestJS auth guard (validates token, builds the request auth-context) → entitlement middleware (subscription-status → feature-flag → numeric-limit, ADR 0009) → `SET LOCAL app.tenant_id` / `app.user_id` → Postgres FORCED RLS. `tenantUid` is NEVER a path, query, or body parameter.\n"
      }
    },
    "schemas": {
      "UuidRef": {
        "$ref": "#/components/schemas/Uuid"
      },
      "DateOnlyRef": {
        "$ref": "#/components/schemas/DateOnly"
      },
      "TimestampRef": {
        "$ref": "#/components/schemas/Timestamp"
      },
      "RateRef": {
        "$ref": "#/components/schemas/Rate"
      },
      "MoneyRef": {
        "$ref": "#/components/schemas/Money"
      },
      "CurrencyCodeRef": {
        "$ref": "#/components/schemas/CurrencyCode"
      },
      "BusinessNoRef": {
        "$ref": "#/components/schemas/BusinessNo"
      },
      "FileDownloadRef": {
        "$ref": "#/components/schemas/FileDownload"
      },
      "AuditMetaRef": {
        "$ref": "#/components/schemas/AuditMeta"
      },
      "CursorPageRef": {
        "$ref": "#/components/schemas/CursorPage"
      },
      "DecisionNoteInput": {
        "type": "object",
        "description": "Generic optional free-text decision body shared by approve/reject/cancel/waive/verify/lock actions in this file — maps to the entity's `decision_note` column (fsd 07 §1.5).",
        "additionalProperties": false,
        "properties": {
          "decision_note": {
            "type": "string"
          }
        }
      },
      "ExpenseCategory": {
        "type": "string",
        "enum": [
          "TRAVEL",
          "MEALS",
          "ACCOMMODATION",
          "LOCAL_TRANSPORT",
          "COMMUNICATION",
          "OFFICE_SUPPLIES",
          "CLIENT_ENTERTAINMENT",
          "MEDICAL",
          "TRAINING",
          "OTHER"
        ],
        "description": "expense.expense_category (db 08 §1.1)."
      },
      "ExpenseClaimType": {
        "type": "string",
        "enum": [
          "REIMBURSEMENT",
          "TRAVEL",
          "ADVANCE_SETTLEMENT"
        ],
        "description": "expense_claims.claim_type (db 08 §1.1)."
      },
      "ExpenseClaimStatus": {
        "type": "string",
        "enum": [
          "DRAFT",
          "SUBMITTED",
          "PENDING_APPROVAL",
          "APPROVED",
          "REIMBURSING",
          "REIMBURSED",
          "REJECTED",
          "CANCELLED"
        ],
        "description": "expense_claims.status lifecycle (db 08 §1.1)."
      },
      "ReceiptStatus": {
        "type": "string",
        "enum": [
          "UPLOADED",
          "VERIFIED",
          "REJECTED",
          "DUPLICATE"
        ],
        "description": "receipts.status (db 08 §1.1)."
      },
      "CapPeriod": {
        "type": "string",
        "enum": [
          "PER_CLAIM",
          "PER_DAY",
          "PER_MONTH",
          "PER_TRIP"
        ],
        "description": "expense_policies.cap_period (db 08 §1.2)."
      },
      "PerDiemCategory": {
        "type": "string",
        "enum": [
          "LODGING",
          "MEALS",
          "INCIDENTALS",
          "LOCAL_TRANSPORT",
          "FULL_DAY"
        ],
        "description": "expense.per_diem_category (db 08 §1.2)."
      },
      "TripType": {
        "type": "string",
        "enum": [
          "DOMESTIC",
          "INTERNATIONAL"
        ],
        "description": "travel_requests.trip_type (db 08 §1.3)."
      },
      "TravelRequestStatus": {
        "type": "string",
        "enum": [
          "DRAFT",
          "SUBMITTED",
          "PENDING_APPROVAL",
          "APPROVED",
          "REJECTED",
          "BOOKED",
          "IN_PROGRESS",
          "COMPLETED",
          "SETTLED",
          "CANCELLED"
        ],
        "description": "travel_requests.status lifecycle (db 08 §1.3)."
      },
      "LegType": {
        "type": "string",
        "enum": [
          "FLIGHT",
          "TRAIN",
          "BUS",
          "ROAD",
          "LOCAL_TRANSPORT",
          "ACCOMMODATION",
          "OTHER"
        ],
        "description": "travel_legs.leg_type (db 08 §1.3)."
      },
      "LegStatus": {
        "type": "string",
        "enum": [
          "PLANNED",
          "BOOKED",
          "COMPLETED",
          "CANCELLED"
        ],
        "description": "travel_legs.status (db 08 §1.3)."
      },
      "TravelAdvanceStatus": {
        "type": "string",
        "enum": [
          "REQUESTED",
          "APPROVED",
          "REJECTED",
          "DISBURSED",
          "PENDING_SETTLEMENT",
          "SETTLED",
          "RECOVERED",
          "CANCELLED"
        ],
        "description": "travel_advances.status lifecycle (db 08 §1.3)."
      },
      "PolicyOverall": {
        "type": "string",
        "enum": [
          "WITHIN",
          "BREACH",
          "OVERRIDE"
        ],
        "description": "policy_snapshot.overall (db 08 §1.1 JSONB shape)."
      },
      "BenefitPlanType": {
        "type": "string",
        "enum": [
          "GMC",
          "GPA",
          "GTL",
          "FLEXIBLE_FBP",
          "OPD",
          "DENTAL",
          "VOLUNTARY",
          "OTHER"
        ],
        "description": "benefits.plan_type (db 08 §2.1)."
      },
      "BenefitPlanStatus": {
        "type": "string",
        "enum": [
          "DRAFT",
          "ACTIVE",
          "RENEWING",
          "EXPIRED",
          "WITHDRAWN"
        ],
        "description": "benefit_plans.status (db 08 §2.1)."
      },
      "CoverageBasis": {
        "type": "string",
        "enum": [
          "EMPLOYEE_ONLY",
          "EMPLOYEE_PLUS_FAMILY",
          "EMPLOYEE_PLUS_DEPENDENTS"
        ],
        "description": "benefit_plans.coverage_basis (db 08 §2.1)."
      },
      "CoverageTier": {
        "type": "string",
        "enum": [
          "EMPLOYEE_ONLY",
          "EMPLOYEE_SPOUSE",
          "EMPLOYEE_FAMILY"
        ],
        "description": "benefit_enrolments.coverage_tier (db 08 §2.1)."
      },
      "BenefitEnrolmentStatus": {
        "type": "string",
        "enum": [
          "PENDING",
          "ENROLLED",
          "ACTIVE",
          "WAIVED",
          "LAPSED",
          "TERMINATED",
          "CANCELLED"
        ],
        "description": "benefit_enrolments.status lifecycle (db 08 §2.1)."
      },
      "MemberType": {
        "type": "string",
        "enum": [
          "EMPLOYEE",
          "SPOUSE",
          "CHILD",
          "PARENT",
          "OTHER_DEPENDENT"
        ],
        "description": "benefits.member_type (db 08 §2.1)."
      },
      "InsuranceRecordStatus": {
        "type": "string",
        "enum": [
          "ACTIVE",
          "EXPIRED",
          "SUSPENDED",
          "CANCELLED"
        ],
        "description": "insurance_records.status (db 08 §2.1)."
      },
      "FbpDeclarationStatus": {
        "type": "string",
        "enum": [
          "DRAFT",
          "DECLARED",
          "SUBMITTED",
          "VERIFIED",
          "LOCKED",
          "REJECTED"
        ],
        "description": "fbp_declarations.status lifecycle (db 08 §2.2)."
      },
      "ReceiptInput": {
        "type": "object",
        "description": "One itemised receipt line submitted with a claim. `storage_key` is the key `xc.file.request_upload_url` (XC-F07, module 13) minted and the client then PUT the image/PDF to, ahead of this call — bytes never transit this API. The server registers the owning `xc.object_refs` row itself (`owner_type = expense.receipts`) when it accepts the claim, which is why the input carries a storage key and not a `file_id`: no `xc.object_refs` row exists yet at upload-url time (see `xc.file.request_upload_url`), so a client can never hold one. The resolved `file_id` comes back on `Receipt.file`. Same contract as `tax.tax_proof.create`.\n",
        "required": [
          "category",
          "amount",
          "storage_key"
        ],
        "additionalProperties": false,
        "properties": {
          "category": {
            "$ref": "#/components/schemas/ExpenseCategory"
          },
          "merchant_name": {
            "type": "string"
          },
          "receipt_date": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DateOnlyRef"
              }
            ],
            "description": "Must not be after the tenant business day."
          },
          "amount": {
            "$ref": "#/components/schemas/MoneyRef"
          },
          "tax_amount": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/MoneyRef"
              },
              {
                "type": "null"
              }
            ],
            "description": "GST/VAT portion for input-credit reporting."
          },
          "storage_key": {
            "type": "string",
            "description": "Object-storage key from `xc.file.request_upload_url`; must sit under the caller's own `<tenantUid>/uploads/` prefix (server-enforced)."
          },
          "content_hash": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional SHA-256 of the uploaded file. Required before Finance can move the receipt to `VERIFIED` (db 08 §1.1 check)."
          }
        }
      },
      "Receipt": {
        "description": "expense.receipts — an itemised, object-stored receipt line on a claim (db 08 §1.1).",
        "allOf": [
          {
            "type": "object",
            "required": [
              "id",
              "expense_claim_id",
              "category",
              "amount",
              "status"
            ],
            "properties": {
              "id": {
                "$ref": "#/components/schemas/UuidRef"
              },
              "expense_claim_id": {
                "$ref": "#/components/schemas/UuidRef"
              },
              "category": {
                "$ref": "#/components/schemas/ExpenseCategory"
              },
              "merchant_name": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "receipt_date": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/DateOnlyRef"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "amount": {
                "$ref": "#/components/schemas/MoneyRef"
              },
              "tax_amount": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/MoneyRef"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "content_hash": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "SHA-256 tamper-evidence hash; required once `status=VERIFIED` (db 08 §1.1 check)."
              },
              "file": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/FileDownloadRef"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "status": {
                "$ref": "#/components/schemas/ReceiptStatus"
              }
            }
          },
          {
            "$ref": "#/components/schemas/AuditMetaRef"
          }
        ]
      },
      "ReceiptReviewInput": {
        "type": "object",
        "required": [
          "status"
        ],
        "additionalProperties": false,
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "VERIFIED",
              "REJECTED",
              "DUPLICATE"
            ]
          },
          "decision_note": {
            "type": "string"
          }
        }
      },
      "PolicySnapshotLine": {
        "type": "object",
        "readOnly": true,
        "description": "One category line of the stamped policy decision (db 08 §1.1 JSONB shape). Amounts are decimal strings in the parent claim/trip's own `currency_code` — the JSONB shape carries no per-line currency.",
        "properties": {
          "category": {
            "$ref": "#/components/schemas/ExpenseCategory"
          },
          "claimed": {
            "type": "string",
            "pattern": "^\\d+(\\.\\d{1,2})?$"
          },
          "cap": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^\\d+(\\.\\d{1,2})?$"
          },
          "per_diem_rate": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^\\d+(\\.\\d{1,2})?$"
          },
          "within_policy": {
            "type": "boolean"
          },
          "breach_reason": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "PolicySnapshot": {
        "type": "object",
        "readOnly": true,
        "description": "The EXP-F04 policy/per-diem decision stamped at submit — schemaless, never queried/joined (db 08 §1.1). `null` before first evaluation.",
        "properties": {
          "policy_id": {
            "$ref": "#/components/schemas/UuidRef"
          },
          "policy_version": {
            "type": "integer"
          },
          "evaluated_at": {
            "$ref": "#/components/schemas/TimestampRef"
          },
          "lines": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PolicySnapshotLine"
            }
          },
          "overall": {
            "$ref": "#/components/schemas/PolicyOverall"
          }
        }
      },
      "ExpenseClaimCreate": {
        "type": "object",
        "required": [
          "expense_date",
          "claimed_amount",
          "title",
          "receipts"
        ],
        "additionalProperties": false,
        "properties": {
          "claim_type": {
            "$ref": "#/components/schemas/ExpenseClaimType"
          },
          "category": {
            "$ref": "#/components/schemas/ExpenseCategory"
          },
          "travel_request_id": {
            "$ref": "#/components/schemas/UuidRef"
          },
          "title": {
            "type": "string"
          },
          "expense_date": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DateOnlyRef"
              }
            ],
            "description": "Must not be after the tenant business day."
          },
          "claimed_amount": {
            "$ref": "#/components/schemas/MoneyRef"
          },
          "receipts": {
            "type": "array",
            "minItems": 1,
            "items": {
              "$ref": "#/components/schemas/ReceiptInput"
            }
          },
          "save_as_draft": {
            "type": "boolean",
            "default": false,
            "description": "When `true`, persists `DRAFT` without evaluating policy or routing to approval (EXP-S04)."
          }
        }
      },
      "ExpenseClaimUpdate": {
        "type": "object",
        "description": "Only permitted while `status=DRAFT`; 409 `STATE_TRANSITION_INVALID` otherwise.",
        "additionalProperties": false,
        "properties": {
          "claim_type": {
            "$ref": "#/components/schemas/ExpenseClaimType"
          },
          "category": {
            "$ref": "#/components/schemas/ExpenseCategory"
          },
          "travel_request_id": {
            "$ref": "#/components/schemas/UuidRef"
          },
          "title": {
            "type": "string"
          },
          "expense_date": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DateOnlyRef"
              }
            ],
            "description": "Must not be after the tenant business day."
          },
          "claimed_amount": {
            "$ref": "#/components/schemas/MoneyRef"
          },
          "receipts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ReceiptInput"
            },
            "description": "Full replace of the claim's receipt set."
          },
          "submit": {
            "type": "boolean",
            "default": false,
            "description": "When `true`, transitions `DRAFT → SUBMITTED` and synchronously evaluates/stamps `policy_snapshot`."
          }
        }
      },
      "ExpenseClaimApprovalInput": {
        "type": "object",
        "description": "Amount cleared, in `base_currency_code`; must be `<= base_amount` (db 08 §1.1 check).",
        "required": [
          "approved_amount"
        ],
        "additionalProperties": false,
        "properties": {
          "approved_amount": {
            "$ref": "#/components/schemas/MoneyRef"
          },
          "decision_note": {
            "type": "string"
          }
        }
      },
      "ExpenseClaim": {
        "description": "expense.expense_claims — the claim envelope from draft to reimbursed (db 08 §1.1). `claimed_amount` is in the spend currency; `base_amount` (`= claimed_amount × fx_rate`) is the payable in the legal entity's book currency (`base_currency_code`); `approved_amount`, when set, is also in book currency.\n",
        "allOf": [
          {
            "type": "object",
            "required": [
              "id",
              "claim_no",
              "employee_id",
              "legal_entity_id",
              "claim_type",
              "claimed_amount",
              "base_amount",
              "base_currency_code",
              "status"
            ],
            "properties": {
              "id": {
                "$ref": "#/components/schemas/UuidRef"
              },
              "claim_no": {
                "$ref": "#/components/schemas/BusinessNoRef"
              },
              "employee_id": {
                "$ref": "#/components/schemas/UuidRef"
              },
              "legal_entity_id": {
                "$ref": "#/components/schemas/UuidRef"
              },
              "claim_type": {
                "$ref": "#/components/schemas/ExpenseClaimType"
              },
              "category": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/ExpenseCategory"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "travel_request_id": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/UuidRef"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "title": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "expense_date": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/DateOnlyRef"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "claimed_amount": {
                "$ref": "#/components/schemas/MoneyRef"
              },
              "base_currency_code": {
                "$ref": "#/components/schemas/CurrencyCodeRef"
              },
              "fx_rate": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/RateRef"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "base_amount": {
                "$ref": "#/components/schemas/MoneyRef"
              },
              "approved_amount": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/MoneyRef"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "policy_snapshot": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/PolicySnapshot"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "status": {
                "$ref": "#/components/schemas/ExpenseClaimStatus"
              },
              "submitted_at": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/TimestampRef"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "submitted_by": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/UuidRef"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "approved_by": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/UuidRef"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "approved_at": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/TimestampRef"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "decision_note": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Approver's reason, shown on `REJECTED` (fsd 07 §1.5)."
              },
              "payout_ref": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Soft `ref→pay` posting id — the `REIMBURSEMENT` earning line (PAY-F04)."
              },
              "reimbursed_at": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/TimestampRef"
                  },
                  {
                    "type": "null"
                  }
                ]
              }
            }
          },
          {
            "$ref": "#/components/schemas/AuditMetaRef"
          }
        ]
      },
      "ExpenseClaimDetail": {
        "description": "EXP-S04 claim detail — the claim plus its receipts.",
        "allOf": [
          {
            "$ref": "#/components/schemas/ExpenseClaim"
          },
          {
            "type": "object",
            "properties": {
              "receipts": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Receipt"
                }
              }
            }
          }
        ]
      },
      "ExpenseClaimPage": {
        "allOf": [
          {
            "$ref": "#/components/schemas/CursorPageRef"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/ExpenseClaim"
                }
              }
            }
          }
        ]
      },
      "ReceiptSummary": {
        "type": "object",
        "readOnly": true,
        "description": "The EXP-S10 **Receipts** column, computed as one lateral aggregate per claim so the grid never fans out a receipt read per row. Counts are integers, not money. A claim with no receipts comes back with a zeroed summary rather than `null` — \"no receipts attached\" and \"receipts not read\" are different facts and the grid must be able to tell them apart.\n",
        "required": [
          "total",
          "by_status"
        ],
        "properties": {
          "total": {
            "type": "integer",
            "minimum": 0
          },
          "by_status": {
            "type": "object",
            "description": "One count per `expense.receipt_status` member; absent statuses report `0`.",
            "required": [
              "UPLOADED",
              "VERIFIED",
              "REJECTED",
              "DUPLICATE"
            ],
            "properties": {
              "UPLOADED": {
                "type": "integer",
                "minimum": 0
              },
              "VERIFIED": {
                "type": "integer",
                "minimum": 0
              },
              "REJECTED": {
                "type": "integer",
                "minimum": 0
              },
              "DUPLICATE": {
                "type": "integer",
                "minimum": 0
              }
            }
          }
        }
      },
      "ExpenseClaimAdminRow": {
        "description": "A claim as the EXP-S10 Finance queue lists it: the claim itself plus the claimant's display identity and its receipt summary, so the console never has to fan out an employee or receipt read per row.\n",
        "allOf": [
          {
            "$ref": "#/components/schemas/ExpenseClaim"
          },
          {
            "type": "object",
            "properties": {
              "employee_name": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "employee_no": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "receipt_summary": {
                "$ref": "#/components/schemas/ReceiptSummary"
              }
            }
          }
        ]
      },
      "ExpenseClaimAdminDetail": {
        "description": "EXP-S10's receipt-viewer drawer — the queue row plus its receipts.",
        "allOf": [
          {
            "$ref": "#/components/schemas/ExpenseClaimAdminRow"
          },
          {
            "type": "object",
            "properties": {
              "receipts": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Receipt"
                }
              }
            }
          }
        ]
      },
      "ExpenseClaimQueueSummaryBand": {
        "type": "object",
        "readOnly": true,
        "required": [
          "count",
          "totals"
        ],
        "properties": {
          "count": {
            "type": "integer",
            "minimum": 0
          },
          "totals": {
            "type": "array",
            "description": "One exact decimal-string total per `base_currency_code` present in the band. An ARRAY, not a scalar, on purpose — book currencies are never summed together (db-docs/00 §6). An empty array means the band holds no claims.\n",
            "items": {
              "$ref": "#/components/schemas/MoneyRef"
            }
          }
        }
      },
      "ExpenseClaimQueueSummary": {
        "type": "object",
        "readOnly": true,
        "description": "The three `PT-KPI` bands of EXP-S10 (fsd 07 §W1).",
        "required": [
          "pending",
          "approved_pending_payment",
          "reimbursed_this_period",
          "period_start",
          "period_end"
        ],
        "properties": {
          "pending": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ExpenseClaimQueueSummaryBand"
              }
            ],
            "description": "`SUBMITTED` + `PENDING_APPROVAL` — totalled on `base_amount` (nothing is cleared yet)."
          },
          "approved_pending_payment": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ExpenseClaimQueueSummaryBand"
              }
            ],
            "description": "`APPROVED` + `REIMBURSING` — totalled on `approved_amount`, what Finance actually cleared."
          },
          "reimbursed_this_period": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ExpenseClaimQueueSummaryBand"
              }
            ],
            "description": "`REIMBURSED` with `reimbursed_at` inside the window below — totalled on `approved_amount`."
          },
          "period_start": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DateOnlyRef"
              }
            ],
            "description": "The window the third band used (current calendar month), returned so the tile names the period instead of asserting one of its own."
          },
          "period_end": {
            "$ref": "#/components/schemas/DateOnlyRef"
          }
        }
      },
      "ExpenseClaimAdminPage": {
        "allOf": [
          {
            "$ref": "#/components/schemas/CursorPageRef"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/ExpenseClaimAdminRow"
                }
              }
            }
          }
        ]
      },
      "ExpenseClaimExportRequest": {
        "type": "object",
        "description": "The EXP-S10 **Export** filter set. Deliberately the SAME vocabulary as `expense.expense_claim.list_admin`, so the exported rows and the rows on screen can never describe two different sets (`claim_type` and `category` added 2026-08-23, #143, for exactly that reason). An empty body exports the whole unfiltered queue, capped at 10,000 rows.\n",
        "additionalProperties": false,
        "properties": {
          "employee_id": {
            "$ref": "#/components/schemas/UuidRef"
          },
          "status": {
            "$ref": "#/components/schemas/ExpenseClaimStatus"
          },
          "claim_type": {
            "$ref": "#/components/schemas/ExpenseClaimType"
          },
          "category": {
            "$ref": "#/components/schemas/ExpenseCategory"
          },
          "expense_date_from": {
            "$ref": "#/components/schemas/DateOnlyRef"
          },
          "expense_date_to": {
            "$ref": "#/components/schemas/DateOnlyRef"
          }
        }
      },
      "ExpensePolicyCreate": {
        "type": "object",
        "description": "`currency_code` is the band's operating currency, carried regardless of whether `cap_amount`/`receipt_required_above` are set (db 08 §1.2 — both are nullable, `currency_code` is not); when either money object IS sent, its own `currency_code` must equal it. `version_no` is deliberately absent — the server derives it (see the operation description).",
        "required": [
          "policy_code",
          "name",
          "legal_entity_id",
          "currency_code",
          "effective_from"
        ],
        "additionalProperties": false,
        "properties": {
          "policy_code": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "legal_entity_id": {
            "$ref": "#/components/schemas/UuidRef"
          },
          "grade_id": {
            "$ref": "#/components/schemas/UuidRef"
          },
          "work_location_id": {
            "$ref": "#/components/schemas/UuidRef"
          },
          "category": {
            "$ref": "#/components/schemas/ExpenseCategory"
          },
          "cap_amount": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/MoneyRef"
              },
              {
                "type": "null"
              }
            ]
          },
          "cap_period": {
            "$ref": "#/components/schemas/CapPeriod"
          },
          "currency_code": {
            "$ref": "#/components/schemas/CurrencyCodeRef"
          },
          "receipt_required_above": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/MoneyRef"
              },
              {
                "type": "null"
              }
            ]
          },
          "requires_approval": {
            "type": "boolean",
            "default": true
          },
          "effective_from": {
            "$ref": "#/components/schemas/DateOnlyRef"
          },
          "effective_to": {
            "$ref": "#/components/schemas/DateOnlyRef"
          }
        }
      },
      "ExpensePolicy": {
        "description": "expense.expense_policies — an effective-dated policy band (db 08 §1.2).",
        "allOf": [
          {
            "type": "object",
            "required": [
              "id",
              "policy_code",
              "name",
              "legal_entity_id",
              "currency_code",
              "version_no",
              "effective_from",
              "is_active"
            ],
            "properties": {
              "id": {
                "$ref": "#/components/schemas/UuidRef"
              },
              "policy_code": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "legal_entity_id": {
                "$ref": "#/components/schemas/UuidRef"
              },
              "grade_id": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/UuidRef"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "work_location_id": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/UuidRef"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "category": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/ExpenseCategory"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "cap_amount": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/MoneyRef"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "cap_period": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/CapPeriod"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "currency_code": {
                "$ref": "#/components/schemas/CurrencyCodeRef"
              },
              "receipt_required_above": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/MoneyRef"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "requires_approval": {
                "type": "boolean"
              },
              "version_no": {
                "type": "integer",
                "minimum": 1
              },
              "effective_from": {
                "$ref": "#/components/schemas/DateOnlyRef"
              },
              "effective_to": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/DateOnlyRef"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "is_active": {
                "type": "boolean"
              }
            }
          },
          {
            "$ref": "#/components/schemas/AuditMetaRef"
          }
        ]
      },
      "ExpensePolicyPage": {
        "allOf": [
          {
            "$ref": "#/components/schemas/CursorPageRef"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/ExpensePolicy"
                }
              }
            }
          }
        ]
      },
      "PerDiemRateCreate": {
        "type": "object",
        "required": [
          "legal_entity_id",
          "category",
          "rate_amount",
          "effective_from"
        ],
        "additionalProperties": false,
        "properties": {
          "legal_entity_id": {
            "$ref": "#/components/schemas/UuidRef"
          },
          "work_location_id": {
            "$ref": "#/components/schemas/UuidRef"
          },
          "location_label": {
            "type": "string"
          },
          "grade_id": {
            "$ref": "#/components/schemas/UuidRef"
          },
          "category": {
            "$ref": "#/components/schemas/PerDiemCategory"
          },
          "rate_amount": {
            "$ref": "#/components/schemas/MoneyRef"
          },
          "effective_from": {
            "$ref": "#/components/schemas/DateOnlyRef"
          },
          "effective_to": {
            "$ref": "#/components/schemas/DateOnlyRef"
          }
        }
      },
      "PerDiemRate": {
        "description": "expense.per_diem_rates — an effective-dated per-diem rate (db 08 §1.2).",
        "allOf": [
          {
            "type": "object",
            "required": [
              "id",
              "legal_entity_id",
              "category",
              "rate_amount",
              "effective_from",
              "is_active"
            ],
            "properties": {
              "id": {
                "$ref": "#/components/schemas/UuidRef"
              },
              "legal_entity_id": {
                "$ref": "#/components/schemas/UuidRef"
              },
              "work_location_id": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/UuidRef"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "location_label": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "grade_id": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/UuidRef"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "category": {
                "$ref": "#/components/schemas/PerDiemCategory"
              },
              "rate_amount": {
                "$ref": "#/components/schemas/MoneyRef"
              },
              "effective_from": {
                "$ref": "#/components/schemas/DateOnlyRef"
              },
              "effective_to": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/DateOnlyRef"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "is_active": {
                "type": "boolean"
              }
            }
          },
          {
            "$ref": "#/components/schemas/AuditMetaRef"
          }
        ]
      },
      "PerDiemRatePage": {
        "allOf": [
          {
            "$ref": "#/components/schemas/CursorPageRef"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/PerDiemRate"
                }
              }
            }
          }
        ]
      },
      "TravelLegInput": {
        "type": "object",
        "required": [
          "leg_no",
          "leg_type",
          "estimated_cost_amount"
        ],
        "additionalProperties": false,
        "properties": {
          "leg_no": {
            "type": "integer",
            "minimum": 1
          },
          "leg_type": {
            "$ref": "#/components/schemas/LegType"
          },
          "from_location": {
            "type": "string"
          },
          "to_location": {
            "type": "string"
          },
          "depart_at": {
            "$ref": "#/components/schemas/TimestampRef"
          },
          "arrive_at": {
            "$ref": "#/components/schemas/TimestampRef"
          },
          "class_of_service": {
            "type": "string"
          },
          "estimated_cost_amount": {
            "$ref": "#/components/schemas/MoneyRef"
          }
        }
      },
      "TravelLeg": {
        "description": "expense.travel_legs — one discrete itinerary leg (db 08 §1.3). `estimated_cost_amount` and the stamped `per_diem_amount` may carry a foreign `currency_code` per destination.",
        "allOf": [
          {
            "type": "object",
            "required": [
              "id",
              "travel_request_id",
              "leg_no",
              "leg_type",
              "estimated_cost_amount",
              "status"
            ],
            "properties": {
              "id": {
                "$ref": "#/components/schemas/UuidRef"
              },
              "travel_request_id": {
                "$ref": "#/components/schemas/UuidRef"
              },
              "leg_no": {
                "type": "integer",
                "minimum": 1
              },
              "leg_type": {
                "$ref": "#/components/schemas/LegType"
              },
              "from_location": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "to_location": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "depart_at": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/TimestampRef"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "arrive_at": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/TimestampRef"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "class_of_service": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "estimated_cost_amount": {
                "$ref": "#/components/schemas/MoneyRef"
              },
              "per_diem_amount": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/MoneyRef"
                  },
                  {
                    "type": "null"
                  }
                ],
                "description": "Stamped from `per_diem_rates` at submit (EXP-F04) — never re-rated by a later config edit."
              },
              "booking_ref": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "status": {
                "$ref": "#/components/schemas/LegStatus"
              }
            }
          },
          {
            "$ref": "#/components/schemas/AuditMetaRef"
          }
        ]
      },
      "TravelRequestCreate": {
        "type": "object",
        "description": "`currency_code` is the trip's header booking currency; `estimated_cost_amount` is server-derived (Σ legs) and not client-submitted.",
        "required": [
          "purpose",
          "start_date",
          "end_date",
          "currency_code",
          "legs"
        ],
        "additionalProperties": false,
        "properties": {
          "purpose": {
            "type": "string"
          },
          "trip_type": {
            "$ref": "#/components/schemas/TripType"
          },
          "start_date": {
            "$ref": "#/components/schemas/DateOnlyRef"
          },
          "end_date": {
            "$ref": "#/components/schemas/DateOnlyRef"
          },
          "currency_code": {
            "$ref": "#/components/schemas/CurrencyCodeRef"
          },
          "legs": {
            "type": "array",
            "minItems": 1,
            "items": {
              "$ref": "#/components/schemas/TravelLegInput"
            }
          }
        }
      },
      "TravelRequest": {
        "description": "expense.travel_requests — the pre-trip authorisation envelope (db 08 §1.3). A `DOMESTIC` trip books in `base_currency_code`; only `INTERNATIONAL` may carry a foreign currency on `estimated_cost_amount` (db 08 §1.3 check).\n",
        "allOf": [
          {
            "type": "object",
            "required": [
              "id",
              "request_no",
              "employee_id",
              "legal_entity_id",
              "purpose",
              "trip_type",
              "start_date",
              "end_date",
              "estimated_cost_amount",
              "base_currency_code",
              "status"
            ],
            "properties": {
              "id": {
                "$ref": "#/components/schemas/UuidRef"
              },
              "request_no": {
                "$ref": "#/components/schemas/BusinessNoRef"
              },
              "employee_id": {
                "$ref": "#/components/schemas/UuidRef"
              },
              "legal_entity_id": {
                "$ref": "#/components/schemas/UuidRef"
              },
              "purpose": {
                "type": "string"
              },
              "trip_type": {
                "$ref": "#/components/schemas/TripType"
              },
              "start_date": {
                "$ref": "#/components/schemas/DateOnlyRef"
              },
              "end_date": {
                "$ref": "#/components/schemas/DateOnlyRef"
              },
              "estimated_cost_amount": {
                "$ref": "#/components/schemas/MoneyRef"
              },
              "base_currency_code": {
                "$ref": "#/components/schemas/CurrencyCodeRef"
              },
              "policy_snapshot": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/PolicySnapshot"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "status": {
                "$ref": "#/components/schemas/TravelRequestStatus"
              },
              "submitted_at": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/TimestampRef"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "submitted_by": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/UuidRef"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "approved_by": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/UuidRef"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "approved_at": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/TimestampRef"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "decision_note": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Approver's reason, shown on `REJECTED` (fsd 07 §1.5)."
              }
            }
          },
          {
            "$ref": "#/components/schemas/AuditMetaRef"
          }
        ]
      },
      "TravelRequestDetail": {
        "description": "EXP-S07 trip detail — the request plus its itinerary, any advance, and linked settling claims.",
        "allOf": [
          {
            "$ref": "#/components/schemas/TravelRequest"
          },
          {
            "type": "object",
            "properties": {
              "legs": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/TravelLeg"
                }
              },
              "advance": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/TravelAdvance"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "linked_claims": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/ExpenseClaim"
                },
                "description": "The `TRAVEL`/`ADVANCE_SETTLEMENT` claims where `travel_request_id` = this trip."
              }
            }
          }
        ]
      },
      "TravelRequestPage": {
        "allOf": [
          {
            "$ref": "#/components/schemas/CursorPageRef"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/TravelRequest"
                }
              }
            }
          }
        ]
      },
      "TravelAdvanceCreate": {
        "type": "object",
        "required": [
          "travel_request_id",
          "requested_amount"
        ],
        "additionalProperties": false,
        "properties": {
          "travel_request_id": {
            "$ref": "#/components/schemas/UuidRef"
          },
          "requested_amount": {
            "$ref": "#/components/schemas/MoneyRef"
          }
        }
      },
      "TravelAdvanceApprovalInput": {
        "type": "object",
        "required": [
          "approved_amount"
        ],
        "additionalProperties": false,
        "properties": {
          "approved_amount": {
            "$ref": "#/components/schemas/MoneyRef"
          },
          "decision_note": {
            "type": "string"
          }
        }
      },
      "TravelAdvanceDisburseInput": {
        "type": "object",
        "description": "`disbursed_amount` defaults to `approved_amount` when omitted.",
        "additionalProperties": false,
        "properties": {
          "disbursed_amount": {
            "$ref": "#/components/schemas/MoneyRef"
          }
        }
      },
      "TravelAdvance": {
        "description": "expense.travel_advances — a cash advance against an approved trip, settled post-trip against actual claimed spend (db 08 §1.3). `requested_amount`/`approved_amount`/`disbursed_amount`/ `settled_amount`/`balance_amount` share the advance's own `currency_code`; `base_currency_code` + `fx_rate` describe the book-currency conversion the net payroll posting uses. `balance_amount` = `disbursed − settled`: `> 0` unspent, recovered from the employee via payroll deduction; `< 0` overspend, additional reimbursement due via payroll earning. Distinct from a salary advance (`pay.salary_advances`, PAY-F06) — this is trip funding, reconciled against actuals.\n",
        "allOf": [
          {
            "type": "object",
            "required": [
              "id",
              "advance_no",
              "travel_request_id",
              "employee_id",
              "requested_amount",
              "disbursed_amount",
              "base_currency_code",
              "settled_amount",
              "balance_amount",
              "status"
            ],
            "properties": {
              "id": {
                "$ref": "#/components/schemas/UuidRef"
              },
              "advance_no": {
                "$ref": "#/components/schemas/BusinessNoRef"
              },
              "travel_request_id": {
                "$ref": "#/components/schemas/UuidRef"
              },
              "employee_id": {
                "$ref": "#/components/schemas/UuidRef"
              },
              "requested_amount": {
                "$ref": "#/components/schemas/MoneyRef"
              },
              "approved_amount": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/MoneyRef"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "disbursed_amount": {
                "$ref": "#/components/schemas/MoneyRef"
              },
              "base_currency_code": {
                "$ref": "#/components/schemas/CurrencyCodeRef"
              },
              "fx_rate": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/RateRef"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "settlement_claim_id": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/UuidRef"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "settled_amount": {
                "$ref": "#/components/schemas/MoneyRef"
              },
              "balance_amount": {
                "$ref": "#/components/schemas/MoneyRef"
              },
              "net_payroll_ref": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Soft `ref→pay` posting id for the net (PAY-F04)."
              },
              "status": {
                "$ref": "#/components/schemas/TravelAdvanceStatus"
              },
              "submitted_by": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/UuidRef"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "approved_by": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/UuidRef"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "approved_at": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/TimestampRef"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "decision_note": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Checker's reason, shown on `REJECTED` (fsd 07 §1.5)."
              },
              "disbursed_at": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/TimestampRef"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "settled_at": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/TimestampRef"
                  },
                  {
                    "type": "null"
                  }
                ]
              }
            }
          },
          {
            "$ref": "#/components/schemas/AuditMetaRef"
          }
        ]
      },
      "TravelAdvancePage": {
        "allOf": [
          {
            "$ref": "#/components/schemas/CursorPageRef"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/TravelAdvance"
                }
              }
            }
          }
        ]
      },
      "DependentPolicy": {
        "type": "object",
        "readOnly": true,
        "description": "Who/how many dependents are coverable — advisory config, never queried/joined (db 08 §2.1 JSONB shape).",
        "properties": {
          "coverable_relationships": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "max_children": {
            "type": "integer"
          },
          "parents_covered": {
            "type": "boolean"
          },
          "spouse_covered": {
            "type": "boolean"
          },
          "age_limits": {
            "type": "object",
            "properties": {
              "child_max": {
                "type": "integer"
              },
              "parent_max": {
                "type": "integer"
              }
            }
          }
        }
      },
      "BenefitPlanCreate": {
        "type": "object",
        "description": "`currency_code` is the plan's operating currency, required regardless of whether `sum_insured_amount` is set (db 08 §2.1 — nullable for `OPD`/`DENTAL`/`VOLUNTARY`/`OTHER`/`FLEXIBLE_FBP`).",
        "required": [
          "plan_code",
          "legal_entity_id",
          "plan_type",
          "currency_code"
        ],
        "additionalProperties": false,
        "properties": {
          "plan_code": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "legal_entity_id": {
            "$ref": "#/components/schemas/UuidRef"
          },
          "plan_type": {
            "$ref": "#/components/schemas/BenefitPlanType"
          },
          "insurer_name": {
            "type": "string"
          },
          "policy_number": {
            "type": "string"
          },
          "coverage_basis": {
            "$ref": "#/components/schemas/CoverageBasis"
          },
          "sum_insured_amount": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/MoneyRef"
              },
              {
                "type": "null"
              }
            ]
          },
          "currency_code": {
            "$ref": "#/components/schemas/CurrencyCodeRef"
          },
          "dependent_policy": {
            "type": "object",
            "properties": {
              "coverable_relationships": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "max_children": {
                "type": "integer"
              },
              "parents_covered": {
                "type": "boolean"
              },
              "spouse_covered": {
                "type": "boolean"
              },
              "age_limits": {
                "type": "object",
                "properties": {
                  "child_max": {
                    "type": "integer"
                  },
                  "parent_max": {
                    "type": "integer"
                  }
                }
              }
            }
          },
          "policy_start_date": {
            "$ref": "#/components/schemas/DateOnlyRef"
          },
          "policy_end_date": {
            "$ref": "#/components/schemas/DateOnlyRef"
          },
          "enrolment_window_start": {
            "$ref": "#/components/schemas/DateOnlyRef"
          },
          "enrolment_window_end": {
            "$ref": "#/components/schemas/DateOnlyRef"
          }
        }
      },
      "BenefitPlanUpdate": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "name": {
            "type": "string"
          },
          "insurer_name": {
            "type": "string"
          },
          "policy_number": {
            "type": "string"
          },
          "coverage_basis": {
            "$ref": "#/components/schemas/CoverageBasis"
          },
          "sum_insured_amount": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/MoneyRef"
              },
              {
                "type": "null"
              }
            ]
          },
          "policy_start_date": {
            "$ref": "#/components/schemas/DateOnlyRef"
          },
          "policy_end_date": {
            "$ref": "#/components/schemas/DateOnlyRef"
          },
          "enrolment_window_start": {
            "$ref": "#/components/schemas/DateOnlyRef"
          },
          "enrolment_window_end": {
            "$ref": "#/components/schemas/DateOnlyRef"
          },
          "status": {
            "$ref": "#/components/schemas/BenefitPlanStatus"
          }
        }
      },
      "BenefitPlan": {
        "description": "benefits.benefit_plans — a pack-driven employer benefit plan (db 08 §2.1).",
        "allOf": [
          {
            "type": "object",
            "required": [
              "id",
              "plan_code",
              "legal_entity_id",
              "plan_type",
              "currency_code",
              "status"
            ],
            "properties": {
              "id": {
                "$ref": "#/components/schemas/UuidRef"
              },
              "plan_code": {
                "type": "string"
              },
              "name": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "legal_entity_id": {
                "$ref": "#/components/schemas/UuidRef"
              },
              "plan_type": {
                "$ref": "#/components/schemas/BenefitPlanType"
              },
              "insurer_name": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "policy_number": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "coverage_basis": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/CoverageBasis"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "sum_insured_amount": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/MoneyRef"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "currency_code": {
                "$ref": "#/components/schemas/CurrencyCodeRef"
              },
              "dependent_policy": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/DependentPolicy"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "pack_version": {
                "type": [
                  "integer",
                  "null"
                ]
              },
              "policy_start_date": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/DateOnlyRef"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "policy_end_date": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/DateOnlyRef"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "enrolment_window_start": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/DateOnlyRef"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "enrolment_window_end": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/DateOnlyRef"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "status": {
                "$ref": "#/components/schemas/BenefitPlanStatus"
              }
            }
          },
          {
            "$ref": "#/components/schemas/AuditMetaRef"
          }
        ]
      },
      "BenefitPlanPage": {
        "allOf": [
          {
            "$ref": "#/components/schemas/CursorPageRef"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/BenefitPlan"
                }
              }
            }
          }
        ]
      },
      "CoveredDependentInput": {
        "type": "object",
        "description": "`sum_insured` is a decimal string in the enrolment's own `currency_code` — the JSONB shape carries no per-member currency (db 08 §2.1).",
        "required": [
          "dependent_id"
        ],
        "additionalProperties": false,
        "properties": {
          "dependent_id": {
            "$ref": "#/components/schemas/UuidRef"
          },
          "relationship": {
            "type": "string"
          },
          "sum_insured": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^\\d+(\\.\\d{1,2})?$"
          }
        }
      },
      "CoveredDependent": {
        "type": "object",
        "readOnly": true,
        "description": "`sum_insured` is a decimal string in the parent enrolment's `currency_code`.",
        "properties": {
          "dependent_id": {
            "$ref": "#/components/schemas/UuidRef"
          },
          "relationship": {
            "type": [
              "string",
              "null"
            ]
          },
          "sum_insured": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^\\d+(\\.\\d{1,2})?$"
          },
          "added_at": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/DateOnlyRef"
              },
              {
                "type": "null"
              }
            ]
          }
        }
      },
      "BenefitEnrolmentCreate": {
        "type": "object",
        "description": "`currency_code` is required regardless of `employee_contribution_amount` (voluntary/top-up share only, db 08 §2.1).",
        "required": [
          "benefit_plan_id",
          "coverage_tier",
          "currency_code"
        ],
        "additionalProperties": false,
        "properties": {
          "benefit_plan_id": {
            "$ref": "#/components/schemas/UuidRef"
          },
          "coverage_tier": {
            "$ref": "#/components/schemas/CoverageTier"
          },
          "covered_dependents": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CoveredDependentInput"
            },
            "description": "Required unless `coverage_tier=EMPLOYEE_ONLY` (db 08 §2.1 check)."
          },
          "employee_contribution_amount": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/MoneyRef"
              },
              {
                "type": "null"
              }
            ]
          },
          "currency_code": {
            "$ref": "#/components/schemas/CurrencyCodeRef"
          }
        }
      },
      "BenefitEnrolmentUpdate": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "covered_dependents": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CoveredDependentInput"
            }
          }
        }
      },
      "BenefitEnrolment": {
        "description": "benefits.benefit_enrolments — an employee's elected cover under a plan (db 08 §2.1).",
        "allOf": [
          {
            "type": "object",
            "required": [
              "id",
              "enrolment_no",
              "benefit_plan_id",
              "employee_id",
              "coverage_tier",
              "employee_contribution_amount",
              "status"
            ],
            "properties": {
              "id": {
                "$ref": "#/components/schemas/UuidRef"
              },
              "enrolment_no": {
                "$ref": "#/components/schemas/BusinessNoRef"
              },
              "benefit_plan_id": {
                "$ref": "#/components/schemas/UuidRef"
              },
              "employee_id": {
                "$ref": "#/components/schemas/UuidRef"
              },
              "coverage_tier": {
                "$ref": "#/components/schemas/CoverageTier"
              },
              "covered_dependents": {
                "type": [
                  "array",
                  "null"
                ],
                "items": {
                  "$ref": "#/components/schemas/CoveredDependent"
                }
              },
              "sum_insured_amount": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/MoneyRef"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "employee_contribution_amount": {
                "$ref": "#/components/schemas/MoneyRef"
              },
              "plan_pack_version": {
                "type": [
                  "integer",
                  "null"
                ]
              },
              "effective_from": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/DateOnlyRef"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "effective_to": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/DateOnlyRef"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "status": {
                "$ref": "#/components/schemas/BenefitEnrolmentStatus"
              }
            }
          },
          {
            "$ref": "#/components/schemas/AuditMetaRef"
          }
        ]
      },
      "BenefitEnrolmentPage": {
        "allOf": [
          {
            "$ref": "#/components/schemas/CursorPageRef"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/BenefitEnrolment"
                }
              }
            }
          }
        ]
      },
      "InsuranceRecordCreate": {
        "type": "object",
        "description": "`currency_code` is required regardless of whether `sum_insured_amount` is set (db 08 §2.1).",
        "required": [
          "benefit_enrolment_id",
          "benefit_plan_id",
          "member_type",
          "member_name",
          "currency_code"
        ],
        "additionalProperties": false,
        "properties": {
          "benefit_enrolment_id": {
            "$ref": "#/components/schemas/UuidRef"
          },
          "benefit_plan_id": {
            "$ref": "#/components/schemas/UuidRef"
          },
          "member_type": {
            "$ref": "#/components/schemas/MemberType"
          },
          "dependent_id": {
            "$ref": "#/components/schemas/UuidRef"
          },
          "member_name": {
            "type": "string"
          },
          "policy_member_id": {
            "type": "string"
          },
          "sum_insured_amount": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/MoneyRef"
              },
              {
                "type": "null"
              }
            ]
          },
          "currency_code": {
            "$ref": "#/components/schemas/CurrencyCodeRef"
          },
          "valid_from": {
            "$ref": "#/components/schemas/DateOnlyRef"
          },
          "expiry_date": {
            "$ref": "#/components/schemas/DateOnlyRef"
          },
          "ecard_file_id": {
            "$ref": "#/components/schemas/UuidRef",
            "description": "Soft `ref→xc.files`, minted by the cross-cutting file-upload operation (XC-F07)."
          }
        }
      },
      "InsuranceRecordUpdate": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "member_name": {
            "type": "string"
          },
          "policy_member_id": {
            "type": "string"
          },
          "sum_insured_amount": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/MoneyRef"
              },
              {
                "type": "null"
              }
            ]
          },
          "valid_from": {
            "$ref": "#/components/schemas/DateOnlyRef"
          },
          "expiry_date": {
            "$ref": "#/components/schemas/DateOnlyRef"
          },
          "ecard_file_id": {
            "$ref": "#/components/schemas/UuidRef"
          },
          "status": {
            "$ref": "#/components/schemas/InsuranceRecordStatus"
          }
        }
      },
      "InsuranceRecord": {
        "description": "benefits.insurance_records — a per-member coverage/e-card record (db 08 §2.1).",
        "allOf": [
          {
            "type": "object",
            "required": [
              "id",
              "benefit_enrolment_id",
              "benefit_plan_id",
              "member_type",
              "member_name",
              "currency_code",
              "status"
            ],
            "properties": {
              "id": {
                "$ref": "#/components/schemas/UuidRef"
              },
              "benefit_enrolment_id": {
                "$ref": "#/components/schemas/UuidRef"
              },
              "benefit_plan_id": {
                "$ref": "#/components/schemas/UuidRef"
              },
              "member_type": {
                "$ref": "#/components/schemas/MemberType"
              },
              "dependent_id": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/UuidRef"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "member_name": {
                "type": "string"
              },
              "policy_member_id": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "sum_insured_amount": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/MoneyRef"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "currency_code": {
                "$ref": "#/components/schemas/CurrencyCodeRef"
              },
              "valid_from": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/DateOnlyRef"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "expiry_date": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/DateOnlyRef"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "ecard": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/FileDownloadRef"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "ecard_content_hash": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "status": {
                "$ref": "#/components/schemas/InsuranceRecordStatus"
              }
            }
          },
          {
            "$ref": "#/components/schemas/AuditMetaRef"
          }
        ]
      },
      "InsuranceRecordPage": {
        "allOf": [
          {
            "$ref": "#/components/schemas/CursorPageRef"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/InsuranceRecord"
                }
              }
            }
          }
        ]
      },
      "FbpAllocationLineInput": {
        "type": "object",
        "description": "`amount` is a decimal string in the declaration's own `currency_code` — the JSONB shape carries no per-line currency (db 08 §2.2).",
        "required": [
          "component_code",
          "amount",
          "pay_component_code"
        ],
        "additionalProperties": false,
        "properties": {
          "component_code": {
            "type": "string"
          },
          "label": {
            "type": "string"
          },
          "amount": {
            "type": "string",
            "pattern": "^\\d+(\\.\\d{1,2})?$"
          },
          "pay_component_code": {
            "type": "string"
          },
          "proof_required": {
            "type": "boolean",
            "default": false
          }
        }
      },
      "FbpAllocationLine": {
        "type": "object",
        "readOnly": true,
        "description": "Per-component allocation with the cap it was validated against, in the declaration's own `currency_code` (db 08 §2.2 JSONB shape).",
        "properties": {
          "component_code": {
            "type": "string"
          },
          "label": {
            "type": [
              "string",
              "null"
            ]
          },
          "amount": {
            "type": "string",
            "pattern": "^\\d+(\\.\\d{1,2})?$"
          },
          "cap": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^\\d+(\\.\\d{1,2})?$"
          },
          "pay_component_code": {
            "type": [
              "string",
              "null"
            ]
          },
          "is_tax_exempt": {
            "type": "boolean"
          },
          "proof_required": {
            "type": "boolean"
          }
        }
      },
      "FbpDeclarationCreate": {
        "type": "object",
        "required": [
          "benefit_plan_id",
          "fiscal_year",
          "allocations"
        ],
        "additionalProperties": false,
        "properties": {
          "benefit_plan_id": {
            "$ref": "#/components/schemas/UuidRef"
          },
          "fiscal_year": {
            "type": "integer",
            "description": "India FY (Apr–Mar), db 08 §2.2."
          },
          "allocations": {
            "type": "array",
            "minItems": 1,
            "items": {
              "$ref": "#/components/schemas/FbpAllocationLineInput"
            }
          }
        }
      },
      "FbpDeclarationUpdate": {
        "type": "object",
        "required": [
          "allocations"
        ],
        "additionalProperties": false,
        "properties": {
          "allocations": {
            "type": "array",
            "minItems": 1,
            "items": {
              "$ref": "#/components/schemas/FbpAllocationLineInput"
            }
          }
        }
      },
      "FbpDeclaration": {
        "description": "benefits.fbp_declarations — an employee's flexible-benefit allocation for a fiscal year (db 08 §2.2). `allocated_amount` (Σ `allocations`) must be `<= total_pot_amount` (db 08 §2.2 check). India-centric tax treatment (BEN-F02); a KSA `FLEXIBLE_FBP` plan carries no `TAX-F02` feed.\n",
        "allOf": [
          {
            "type": "object",
            "required": [
              "id",
              "declaration_no",
              "employee_id",
              "benefit_plan_id",
              "fiscal_year",
              "total_pot_amount",
              "allocated_amount",
              "status"
            ],
            "properties": {
              "id": {
                "$ref": "#/components/schemas/UuidRef"
              },
              "declaration_no": {
                "$ref": "#/components/schemas/BusinessNoRef"
              },
              "employee_id": {
                "$ref": "#/components/schemas/UuidRef"
              },
              "benefit_plan_id": {
                "$ref": "#/components/schemas/UuidRef"
              },
              "fiscal_year": {
                "type": "integer"
              },
              "total_pot_amount": {
                "$ref": "#/components/schemas/MoneyRef"
              },
              "allocated_amount": {
                "$ref": "#/components/schemas/MoneyRef"
              },
              "allocations": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/FbpAllocationLine"
                }
              },
              "plan_pack_version": {
                "type": [
                  "integer",
                  "null"
                ]
              },
              "window_start": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/DateOnlyRef"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "window_end": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/DateOnlyRef"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "status": {
                "$ref": "#/components/schemas/FbpDeclarationStatus"
              },
              "submitted_at": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/TimestampRef"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "verified_by": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/UuidRef"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "decision_note": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Verifier's reason, shown on `REJECTED` (fsd 07 §1.5)."
              },
              "locked_at": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/TimestampRef"
                  },
                  {
                    "type": "null"
                  }
                ]
              }
            }
          },
          {
            "$ref": "#/components/schemas/AuditMetaRef"
          }
        ]
      },
      "FbpDeclarationPage": {
        "allOf": [
          {
            "$ref": "#/components/schemas/CursorPageRef"
          },
          {
            "type": "object",
            "properties": {
              "data": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/FbpDeclaration"
                }
              }
            }
          }
        ]
      },
      "Uuid": {
        "type": "string",
        "format": "uuid",
        "description": "UUIDv7 surrogate primary key (db-docs/00 §3). Never the business identifier."
      },
      "DateOnly": {
        "type": "string",
        "format": "date",
        "description": "Calendar-only value (pay-period date, leave date, due date)."
      },
      "Timestamp": {
        "type": "string",
        "format": "date-time",
        "description": "timestamptz, serialized UTC ISO-8601. Presentation timezone is a client concern."
      },
      "Rate": {
        "type": "string",
        "pattern": "^-?\\d+(\\.\\d{1,6})?$",
        "description": "numeric(9,6) fraction as a string, e.g. \"0.120000\" for the 12% EPF rate. Never a float; percentages are stored as fractions."
      },
      "Money": {
        "type": "object",
        "description": "Exact decimal money (db-docs/00 §6). `amount` is a STRING so float never enters the wire.",
        "required": [
          "amount",
          "currency_code"
        ],
        "additionalProperties": false,
        "properties": {
          "amount": {
            "type": "string",
            "pattern": "^-?\\d+(\\.\\d{1,2})?$",
            "description": "numeric(18,2) as a string, e.g. \"45000.00\"."
          },
          "currency_code": {
            "$ref": "#/components/schemas/CurrencyCode"
          }
        }
      },
      "CurrencyCode": {
        "type": "string",
        "enum": [
          "INR",
          "SAR"
        ],
        "description": "ISO-4217. A legal entity operates in a single currency (db-docs/00 §6)."
      },
      "BusinessNo": {
        "type": "string",
        "description": "Tenant-unique, prefixed human reference (`employee_no`, `requisition_no`, `offer_no`, `payslip_no`, `claim_no`, `ticket_no`, `asset_no`, `case_no`). Read-model field; never a path key.\n"
      },
      "FileDownload": {
        "type": "object",
        "description": "Authorized file handle (db-docs/00 §14, xc.files). Bytes never transit the API — the backend mints a time-limited presigned URL after authorization. Clients never see storage keys or hold storage credentials; the presigned URL is never persisted.\n",
        "required": [
          "file_id",
          "file_name",
          "url",
          "expires_at"
        ],
        "properties": {
          "file_id": {
            "$ref": "#/components/schemas/Uuid"
          },
          "file_name": {
            "type": "string"
          },
          "mime_type": {
            "type": "string"
          },
          "size_bytes": {
            "type": "integer"
          },
          "content_hash": {
            "type": [
              "string",
              "null"
            ],
            "description": "SHA-256",
            "present where tamper-evidence matters (payslips": null,
            "letters": null,
            "e-sign artifacts).": null
          },
          "url": {
            "type": "string",
            "format": "uri",
            "description": "Time-limited presigned URL."
          },
          "expires_at": {
            "$ref": "#/components/schemas/Timestamp"
          }
        }
      },
      "AuditMeta": {
        "type": "object",
        "description": "Standard mutable-entity columns (db-docs/00 §5). Read-only; present on every mutable read-model.",
        "readOnly": true,
        "properties": {
          "created_at": {
            "$ref": "#/components/schemas/Timestamp"
          },
          "created_by": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              },
              {
                "type": "null"
              }
            ],
            "description": "null = system/jobs"
          },
          "updated_at": {
            "$ref": "#/components/schemas/Timestamp"
          },
          "updated_by": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Uuid"
              },
              {
                "type": "null"
              }
            ]
          },
          "deleted_at": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Timestamp"
              },
              {
                "type": "null"
              }
            ],
            "description": "soft-delete marker; live rows are null. Deleted rows are excluded by default scope."
          },
          "version": {
            "type": "integer",
            "description": "Optimistic-lock counter (where present); surfaces as the ETag."
          }
        }
      },
      "CursorPage": {
        "type": "object",
        "description": "Generic cursor-pagination envelope. List operations compose it via allOf to type `data`, e.g. `allOf: [ {$ref CursorPage}, { properties: { data: { items: {$ref Employee} } } } ]`.\n",
        "required": [
          "data",
          "page"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {}
          },
          "page": {
            "type": "object",
            "required": [
              "has_more"
            ],
            "properties": {
              "next_cursor": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "prev_cursor": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "has_more": {
                "type": "boolean"
              },
              "total_est": {
                "type": [
                  "integer",
                  "null"
                ],
                "description": "Optional, capped, APPROXIMATE row estimate for grid \"X of Z\" display only — never an exact COUNT(*) on large tables (attend.attendance_records, xc.notifications, audit.*).\n"
              }
            }
          }
        }
      },
      "Problem": {
        "type": "object",
        "description": "RFC 9457 problem detail (application/problem+json). The platform-wide error envelope (03 §1).",
        "required": [
          "type",
          "title",
          "status"
        ],
        "properties": {
          "type": {
            "type": "string",
            "format": "uri",
            "default": "about:blank",
            "description": "Problem-type URI."
          },
          "title": {
            "type": "string",
            "description": "Short, human-readable summary (stable per type)."
          },
          "status": {
            "type": "integer",
            "description": "HTTP status code, duplicated for convenience."
          },
          "detail": {
            "type": "string",
            "description": "Human-readable explanation specific to this occurrence."
          },
          "instance": {
            "type": "string",
            "description": "URI reference for this specific occurrence."
          },
          "code": {
            "$ref": "#/components/schemas/ErrorCode"
          },
          "correlation_id": {
            "$ref": "#/components/schemas/Uuid"
          }
        }
      },
      "ValidationProblem": {
        "description": "422 field-level validation failure; extends Problem with a per-field error array. `detail` is ALWAYS present on a 422 (#1251) and is the human summary of `errors[]`: one offending field renders as `\"<field>: <its message>\"` (`withholding_amount: is required for an India entity`), several as `\"N fields were refused: a, b, c.\"`, capped at five names. It is display copy derived from members already in the same body — clients keep branching on `code` and mapping `errors[].pointer` back to a control, never parsing this sentence.\n",
        "allOf": [
          {
            "$ref": "#/components/schemas/Problem"
          },
          {
            "type": "object",
            "required": [
              "detail",
              "errors"
            ],
            "properties": {
              "detail": {
                "type": "string",
                "description": "Human summary of `errors[]`, always populated on a 422 so a client never has to fall back to generic copy for the one status that names a fixable field.\n",
                "example": "withholding_amount: is required for an India entity"
              },
              "errors": {
                "type": "array",
                "items": {
                  "type": "object",
                  "required": [
                    "pointer",
                    "rule"
                  ],
                  "properties": {
                    "pointer": {
                      "type": "string",
                      "description": "JSON Pointer to the offending field, e.g. /claim_amount"
                    },
                    "rule": {
                      "type": "string",
                      "enum": [
                        "required",
                        "format",
                        "length",
                        "range",
                        "cross-field",
                        "async-server",
                        "consent-gated",
                        "uniqueness-business",
                        "not_found"
                      ],
                      "description": "FSD validation taxonomy rule (fsd-docs/00 §8.2). `not_found` is the server-side-lookup arm: a body field that REFERENCES another resource (e.g. `project_id` on a work entry) and did not resolve for this caller. It is reported here, under the field's pointer, and NOT as a 404 — the request addresses its own resource, so the failure belongs on the form field the client can actually fix (#805).\n"
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        ]
      },
      "ErrorCode": {
        "type": "string",
        "description": "Machine-stable error code (paired with the HTTP status; drives client handling, not display copy).",
        "enum": [
          "VALIDATION_FAILED",
          "IDEMPOTENCY_KEY_REUSE",
          "VERSION_CONFLICT",
          "PRECONDITION_REQUIRED",
          "MAKER_EQUALS_CHECKER",
          "STEP_UP_REQUIRED",
          "CONSENT_REQUIRED",
          "TOKEN_DENIED",
          "SCOPE_DENIED",
          "OWNERSHIP_DENIED",
          "STATE_TRANSITION_INVALID",
          "FACE_MISMATCH",
          "FACE_VERIFICATION_REQUIRED",
          "WITHHOLDING_REVIEW_REQUIRED",
          "FEATURE_NOT_IN_PLAN",
          "PLAN_LIMIT_EXCEEDED",
          "TENANT_PAST_DUE",
          "TENANT_SUSPENDED",
          "TENANT_CANCELLED",
          "RATE_LIMITED",
          "NOT_FOUND"
        ]
      }
    },
    "parameters": {
      "PathId": {
        "name": "id",
        "in": "path",
        "required": true,
        "description": "UUIDv7 surrogate key of the target resource. Business numbers (`employee_no`, `claim_no`, …) are read-model fields, never path keys.",
        "schema": {
          "$ref": "#/components/schemas/Uuid"
        }
      },
      "PageSize": {
        "name": "page[size]",
        "in": "query",
        "required": false,
        "description": "Max items per page. Cursor pagination only (03 §2); offset pagination is rejected (ADR 0015).",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "maximum": 200,
          "default": 50
        }
      },
      "PageAfter": {
        "name": "page[after]",
        "in": "query",
        "required": false,
        "description": "Opaque forward keyset cursor (from a prior page's `page.next_cursor`).",
        "schema": {
          "type": "string"
        }
      },
      "PageBefore": {
        "name": "page[before]",
        "in": "query",
        "required": false,
        "description": "Opaque backward keyset cursor (from a prior page's `page.prev_cursor`).",
        "schema": {
          "type": "string"
        }
      },
      "SortParam": {
        "name": "sort",
        "in": "query",
        "required": false,
        "description": "Comma-separated sort keys; leading `-` = descending. Each key MUST be in the operation's documented sort whitelist (free-form sort is rejected so the keyset cursor stays stable).\n",
        "schema": {
          "type": "string"
        }
      },
      "AcceptLanguage": {
        "name": "Accept-Language",
        "in": "header",
        "required": false,
        "description": "Locale for server-rendered/localized text (LocalizedText resolution, letters, notifications). Active locale set comes from the legal entity's compliance pack; KSA tenants default `ar`.\n",
        "schema": {
          "type": "string",
          "enum": [
            "en",
            "ar"
          ],
          "default": "en"
        }
      },
      "IdempotencyKey": {
        "name": "Idempotency-Key",
        "in": "header",
        "required": true,
        "description": "Client-generated unique key. REQUIRED on every mutation (this round tightens ADR 0015's \"platform + retryable mutations\" floor to ALL mutations for uniformity — offline punch/leave sync depends on it). Scoped (tenant, principal, route, key); a replay within the ~24h window returns the stored response with `Idempotency-Replayed: true`; the same key with a different body → 409 IDEMPOTENCY_KEY_REUSE (04 §1).\n",
        "schema": {
          "type": "string",
          "minLength": 8,
          "maxLength": 255
        }
      },
      "IfMatch": {
        "name": "If-Match",
        "in": "header",
        "required": true,
        "description": "Optimistic-concurrency precondition for mutating a VERSIONED mutable entity (db-docs/00 §5 applies `version` where concurrent edits are likely). Value is the entity's current ETag (the row `version`). Absent → 428; stale → 412 (04 §2). N/A for append-only entities and for unversioned low-contention entities (their update ops simply omit this parameter).\n",
        "schema": {
          "type": "string"
        }
      }
    },
    "responses": {
      "Unauthorized": {
        "description": "Missing, expired, or invalid session token (no authenticated principal).",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            }
          }
        }
      },
      "Forbidden": {
        "description": "Authenticated but denied — permission token not granted, out of scope (self/team/branch), not the owner, tenant suspended, or an MC-2 operation without a fresh step-up challenge. `code` ∈ TOKEN_DENIED | SCOPE_DENIED | OWNERSHIP_DENIED | MAKER_EQUALS_CHECKER | STEP_UP_REQUIRED | CONSENT_REQUIRED | TENANT_SUSPENDED. A plan feature-flag being off is 402 FEATURE_NOT_IN_PLAN, not 403 (see PaymentRequired).\n",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            }
          }
        }
      },
      "NotFound": {
        "description": "Resource does not exist OR is masked by RLS (tenant/self/team/branch scope) — the API does not distinguish, so existence is never confirmed across a scope boundary (02 §4 disclosure posture).\n",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            }
          }
        }
      },
      "Conflict": {
        "description": "Idempotency-key reuse with a different body, an invalid state transition, or a uniqueness/business-rule violation (fsd 00 §8.2). For database-backed uniqueness rules, detail names the exact violated rule; unmapped constraints are not collapsed into a generic 409.\n",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            }
          }
        }
      },
      "UnprocessableEntity": {
        "description": "Field-level validation failed. The body carries both `errors[]` (per-field, pointer-addressed) and a `detail` summarising them — never an empty `detail` (#1251).\n",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ValidationProblem"
            },
            "examples": {
              "singleField": {
                "summary": "One refused field — `detail` names it",
                "value": {
                  "type": "about:blank",
                  "title": "Unprocessable Entity",
                  "status": 422,
                  "code": "VALIDATION_FAILED",
                  "detail": "withholding_amount: is required for an India entity",
                  "errors": [
                    {
                      "pointer": "/withholding_amount",
                      "rule": "required",
                      "message": "is required for an India entity"
                    }
                  ]
                }
              },
              "severalFields": {
                "summary": "Several refused fields — `detail` counts and names them",
                "value": {
                  "type": "about:blank",
                  "title": "Unprocessable Entity",
                  "status": 422,
                  "code": "VALIDATION_FAILED",
                  "detail": "2 fields were refused: effective_from, cap_amount.amount.",
                  "errors": [
                    {
                      "pointer": "/effective_from",
                      "rule": "cross-field",
                      "message": "Overlaps an existing version."
                    },
                    {
                      "pointer": "/cap_amount/amount",
                      "rule": "range",
                      "message": "Must be a non-negative decimal string."
                    }
                  ]
                }
              }
            }
          }
        }
      },
      "Locked": {
        "description": "Tenant subscription `past_due` (ADR 0009): WRITES are blocked (423), reads still succeed. `code` = TENANT_PAST_DUE. Mutations return this; list/get operations do not.\n",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            }
          }
        }
      },
      "TooManyRequests": {
        "description": "Per-principal/route rate limit exceeded.",
        "headers": {
          "Retry-After": {
            "$ref": "#/components/headers/RetryAfter"
          }
        },
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            }
          }
        }
      },
      "PreconditionRequired": {
        "description": "If-Match header absent on a mutation of a versioned mutable entity (428).",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            }
          }
        }
      },
      "PreconditionFailed": {
        "description": "If-Match / ETag mismatch — the row changed since it was read (412, VERSION_CONFLICT).",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            }
          }
        }
      }
    },
    "headers": {
      "ETag": {
        "description": "Strong validator of the row `version` (e.g. `\"v7\"`). Use as `If-Match` on the next mutation.",
        "schema": {
          "type": "string"
        }
      },
      "Location": {
        "description": "URI of the created/affected resource.",
        "schema": {
          "type": "string",
          "format": "uri-reference"
        }
      },
      "IdempotencyReplayed": {
        "description": "`true` when a stored idempotent response was replayed rather than freshly computed.",
        "schema": {
          "type": "boolean"
        }
      },
      "RetryAfter": {
        "description": "Seconds to wait before retrying (on 429 / 503).",
        "schema": {
          "type": "integer"
        }
      }
    }
  }
}