openapi: 3.0.3 info: title: BenefitsGraph API version: 0.1.0 description: | Adjudicates employee health-insurance claims against a versioned, per-employer **policy rules engine** — deductibles, co-pay, waiting periods and limits — with idempotent claim submission and a full audit trail. ### Getting started 1. **POST `/auth/guest`** — get a free sandbox API key (the landing page's *"Try as guest"* button does this for you). No signup, no password. 2. Click **Authorize** (top-right) and paste the key. 3. **GET `/policies`** — see the employer / plan pairs you can enrol against (open). 4. **POST `/employees`** — enrol someone using one of those pairs. 5. **POST `/claims`** — submit a claim (needs an `Idempotency-Key` header). 6. **GET `/audit/claims/{claimId}`** — see exactly how it was adjudicated. Every request body below is pre-filled with a working example — just **Authorize**, then **Try it out → Execute**. ### Your sandbox Your key gives you an **isolated sandbox** — your enrolments and claims are yours alone, so the example `EMP-1001` never collides with anyone else's. Sandboxes are automatically **wiped 48 hours** after their last request, so demo data never piles up. ### Seeded policies | employerName | planName | shape | |---|---|---| | `Northwind Traders` | `Standard` | deductible + 10% co-pay, 90-day waiting period | | `Contoso Labs` | `Premium` | zero cost-share, 30-day waiting period | | `Fabrikam Retail` | `Basic` | tightly capped sub-limits, long waits | > A claim submitted right after enrolment comes back `denied / WAITING_PERIOD_NOT_MET`. > That is the rules engine working correctly, not an error. servers: - url: / components: securitySchemes: ApiKeyAuth: type: apiKey in: header name: X-API-Key description: A sandbox key from `POST /auth/guest`. Send it on every protected request. security: - ApiKeyAuth: [] tags: - name: Auth description: Mint an ephemeral sandbox API key. No signup, no password, no key required to call this. - name: Policies description: Reference data — the employer/plan policies you can enrol against. Open, no key required. - name: Employees description: Enrol employees against a policy and read their enrolment. Scoped to your sandbox. - name: Claims description: Submit claims for adjudication (idempotent) and read them back. - name: Audit description: Append-only adjudication trail for each claim. paths: /auth/guest: post: tags: [Auth] summary: Mint an ephemeral guest API key (no signup, no password) description: Returns a sandbox `apiKey`. Paste it into **Authorize**. The sandbox and all its data are wiped 48h after last use. security: [] responses: "201": { description: A new guest key and account id } /policies: get: tags: [Policies] summary: List available employer/plan policies to enrol against description: Discover valid `employerName` / `planName` values (and each plan's rules). Open — no key required. security: [] responses: "200": { description: List of available policies } /employees: post: tags: [Employees] summary: Enroll an employee against an employer's policy description: The `employerName` / `planName` must match a policy from **GET /policies**, otherwise you get `404 Policy not found`. requestBody: required: true content: application/json: schema: type: object required: [externalId, fullName, employerName, planName] properties: externalId: { type: string } fullName: { type: string } employerName: { type: string } planName: { type: string } examples: contoso: summary: Contoso Labs / Premium (zero cost-share) value: externalId: "EMP-1001" fullName: "Ada Lovelace" employerName: "Contoso Labs" planName: "Premium" northwind: summary: Northwind Traders / Standard (deductible + co-pay) value: externalId: "EMP-1002" fullName: "Grace Hopper" employerName: "Northwind Traders" planName: "Standard" fabrikam: summary: Fabrikam Retail / Basic (tightly capped) value: externalId: "EMP-1003" fullName: "Alan Turing" employerName: "Fabrikam Retail" planName: "Basic" responses: "201": { description: Employee enrolled } "401": { description: Missing or invalid API key } "404": { description: Policy not found } "409": { description: Already enrolled in this sandbox } /employees/{externalId}: get: tags: [Employees] summary: Fetch an employee's enrollment and policy details parameters: - name: externalId in: path required: true schema: { type: string, example: "EMP-1001" } responses: "200": { description: Employee found } "401": { description: Missing or invalid API key } "404": { description: Employee not found } /claims: post: tags: [Claims] summary: Submit a claim for adjudication description: | Requires an **`Idempotency-Key`** header. Re-sending the same key replays the original adjudication instead of processing the claim twice. parameters: - name: Idempotency-Key in: header required: true description: Any unique string per claim (a UUID works well). schema: { type: string, example: "11111111-2222-3333-4444-555555555555" } requestBody: required: true content: application/json: schema: type: object required: [employeeExternalId, claimType, billedAmountPaise] properties: employeeExternalId: { type: string } claimType: { type: string, example: opd } billedAmountPaise: { type: integer, minimum: 1 } providerRef: { type: string } examples: opd: summary: Outpatient claim (₹2,500) value: employeeExternalId: "EMP-1001" claimType: "opd" billedAmountPaise: 250000 providerRef: "PRV-1001" dental: summary: Dental claim (₹10,000 — sub-limit applies) value: employeeExternalId: "EMP-1001" claimType: "dental" billedAmountPaise: 1000000 providerRef: "PRV-1001" responses: "201": { description: Claim adjudicated (approved, partial, or denied) } "400": { description: Validation error or missing Idempotency-Key } "401": { description: Missing or invalid API key } "409": { description: Duplicate request currently in flight } /claims/{id}: get: tags: [Claims] summary: Fetch a claim by id parameters: - name: id in: path required: true schema: { type: string, format: uuid } responses: "200": { description: Claim found } "401": { description: Missing or invalid API key } "404": { description: Claim not found } /audit/claims/{claimId}: get: tags: [Audit] summary: Fetch the audit trail for a claim parameters: - name: claimId in: path required: true schema: { type: string, format: uuid } responses: "200": { description: Ordered list of audit events for the claim } "401": { description: Missing or invalid API key }