# ============================================================================= # FICTIONAL training API — synthetic motor-claims sample. Not a real service. # Used throughout the wiki (ch 03, 04, 08) and training sessions D1-D3. # View it: open https://editor.swagger.io and paste this file's contents. # ============================================================================= openapi: 3.0.3 info: title: Claims API (synthetic training sample) version: 1.2.0 description: | API for registering and tracking motor claims (FNOL - First Notice of Loss) at a fictional insurer. Consumers: partner portals, broker systems, internal channels. All timestamps are UTC, ISO 8601. All monetary amounts in EUR. contact: name: Integration Team (fictional) email: api-support@balticshield.example servers: - url: https://api.balticshield.example/claims/v1 description: Production (fictional) - url: https://sandbox.api.balticshield.example/claims/v1 description: Sandbox - test data only (fictional) tags: - name: Claims description: Register and track claims - name: Policies description: Policy lookups needed during claim registration security: - oauth2: [] paths: /claims: post: tags: [Claims] summary: Register a new claim (FNOL) description: | Registers a First Notice of Loss. The policy must exist and be ACTIVE on the incident date, otherwise the request is rejected with 400 (code POLICY_NOT_ACTIVE). **Idempotency:** consumers MUST send an Idempotency-Key header. Retrying with the same key returns the originally created claim instead of creating a duplicate. operationId: registerClaim security: - oauth2: [claims:write] parameters: - $ref: '#/components/parameters/IdempotencyKey' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ClaimSubmission' example: policyNumber: "MTPL-2026-104782" incidentDate: "2026-06-05T17:40:00Z" incidentType: "COLLISION" description: "Rear-ended at traffic lights on Brivibas street." vehicle: registrationNumber: "JK8472" vin: "WVWZZZ1JZXW000341" claimant: firstName: "Jane" lastName: "Berzina" email: "anna.berzina@example.com" phone: "+371 20000000" damages: - area: "REAR" severity: "MODERATE" responses: '201': description: Claim registered. headers: Location: description: URL of the created claim. schema: type: string example: /claims/CLM-2026-000871 content: application/json: schema: $ref: '#/components/schemas/Claim' '400': description: | Validation failed. Error codes include VALIDATION_ERROR, POLICY_NOT_ACTIVE, INCIDENT_DATE_IN_FUTURE. content: application/json: schema: $ref: '#/components/schemas/Error' example: code: "POLICY_NOT_ACTIVE" message: "Policy MTPL-2026-104782 was not active on the incident date." details: [] traceId: "9f1c0a7e-31" '401': description: Missing or invalid access token. '403': description: Token valid but lacks the claims:write scope. '404': description: Policy number not found. '409': description: A claim for the same policy and incident already exists (code DUPLICATE_CLAIM). content: application/json: schema: $ref: '#/components/schemas/Error' get: tags: [Claims] summary: Search claims description: Returns a paginated list filtered by the query parameters. operationId: searchClaims security: - oauth2: [claims:read] parameters: - name: policyNumber in: query schema: type: string - name: status in: query schema: $ref: '#/components/schemas/ClaimStatus' - name: registeredFrom in: query description: Only claims registered on/after this date. schema: type: string format: date - name: page in: query schema: type: integer minimum: 1 default: 1 - name: pageSize in: query schema: type: integer minimum: 1 maximum: 100 default: 20 responses: '200': description: Page of claims (empty list if nothing matches). content: application/json: schema: $ref: '#/components/schemas/ClaimPage' '400': description: Invalid query parameters. '401': description: Missing or invalid access token. /claims/{claimId}: get: tags: [Claims] summary: Get one claim by ID operationId: getClaim security: - oauth2: [claims:read] parameters: - name: claimId in: path required: true description: Claim identifier, format CLM-YYYY-NNNNNN. schema: type: string pattern: '^CLM-\d{4}-\d{6}$' example: "CLM-2026-000871" responses: '200': description: The claim. content: application/json: schema: $ref: '#/components/schemas/Claim' '401': description: Missing or invalid access token. '404': description: No claim with this ID. /policies/{policyNumber}: get: tags: [Policies] summary: Get policy summary description: | Lightweight policy lookup used to validate a policy before registering a claim. Returns coverage status and the insured vehicle. operationId: getPolicySummary security: - oauth2: [policies:read] parameters: - name: policyNumber in: path required: true schema: type: string example: "MTPL-2026-104782" responses: '200': description: Policy summary. content: application/json: schema: $ref: '#/components/schemas/PolicySummary' '401': description: Missing or invalid access token. '404': description: Policy number not found. components: securitySchemes: oauth2: type: oauth2 description: Machine-to-machine authentication (client credentials). flows: clientCredentials: tokenUrl: https://auth.balticshield.example/oauth2/token scopes: claims:read: Read claims claims:write: Register claims policies:read: Read policy summaries parameters: IdempotencyKey: name: Idempotency-Key in: header required: true description: | Unique key (UUID recommended) per logical submission. Lets the API safely de-duplicate retries after timeouts. schema: type: string maxLength: 64 example: "7f9d2c4e-8a13-4f60-b2aa-3d5e9c1b7a20" schemas: ClaimSubmission: type: object description: Payload to register a new claim (FNOL). required: [policyNumber, incidentDate, incidentType, description, claimant] properties: policyNumber: type: string description: Policy the claim is made against. example: "MTPL-2026-104782" incidentDate: type: string format: date-time description: When the incident happened (UTC). Must not be in the future. incidentType: type: string description: Category of the incident. enum: [COLLISION, THEFT, GLASS, WEATHER, VANDALISM, FIRE, OTHER] description: type: string maxLength: 2000 description: Free-text description by the claimant. vehicle: $ref: '#/components/schemas/Vehicle' claimant: $ref: '#/components/schemas/Claimant' damages: type: array description: Damaged areas. Optional at FNOL, can be added later. items: $ref: '#/components/schemas/Damage' Claimant: type: object required: [firstName, lastName] properties: firstName: type: string maxLength: 100 lastName: type: string maxLength: 100 personalCode: type: string description: | National personal identification code. Sensitive personal data - only send when required for the claim, never log it. example: "010190-12345" email: type: string format: email phone: type: string description: International format recommended (+371...). Vehicle: type: object required: [registrationNumber] properties: registrationNumber: type: string description: National registration (licence plate) number. example: "JK8472" vin: type: string description: 17-character Vehicle Identification Number, if known. minLength: 17 maxLength: 17 Damage: type: object required: [area, severity] properties: area: type: string enum: [FRONT, REAR, LEFT_SIDE, RIGHT_SIDE, ROOF, GLASS, INTERIOR, MECHANICAL, OTHER] severity: type: string enum: [MINOR, MODERATE, SEVERE, TOTAL_LOSS] ClaimStatus: type: string description: Lifecycle status of a claim. enum: [REGISTERED, UNDER_REVIEW, APPROVED, REJECTED, CLOSED] Claim: type: object description: A registered claim as stored by the insurer. required: [claimId, status, registeredAt, policyNumber, incidentDate, incidentType] properties: claimId: type: string pattern: '^CLM-\d{4}-\d{6}$' example: "CLM-2026-000871" status: $ref: '#/components/schemas/ClaimStatus' statusReason: type: string description: Filled when status is REJECTED or CLOSED. registeredAt: type: string format: date-time policyNumber: type: string incidentDate: type: string format: date-time incidentType: type: string enum: [COLLISION, THEFT, GLASS, WEATHER, VANDALISM, FIRE, OTHER] description: type: string vehicle: $ref: '#/components/schemas/Vehicle' claimant: $ref: '#/components/schemas/Claimant' damages: type: array items: $ref: '#/components/schemas/Damage' ClaimPage: type: object required: [items, page, pageSize, totalItems, totalPages] properties: items: type: array items: $ref: '#/components/schemas/Claim' page: type: integer example: 1 pageSize: type: integer example: 20 totalItems: type: integer example: 137 totalPages: type: integer example: 7 PolicySummary: type: object required: [policyNumber, status, product, validFrom, validTo] properties: policyNumber: type: string example: "MTPL-2026-104782" status: type: string enum: [ACTIVE, LAPSED, CANCELLED, EXPIRED] product: type: string description: Non-life product line. enum: [MTPL, CASCO, PROPERTY, TRAVEL, LIABILITY] validFrom: type: string format: date validTo: type: string format: date insuredVehicle: $ref: '#/components/schemas/Vehicle' Error: type: object description: Standard error body for 4xx/5xx responses with content. required: [code, message] properties: code: type: string description: Machine-readable error code (stable, documented). example: "VALIDATION_ERROR" message: type: string description: Human-readable explanation. Never contains personal data. details: type: array description: Field-level issues, when applicable. items: type: object properties: field: type: string example: "claimant.email" issue: type: string example: "must be a valid email address" traceId: type: string description: Correlation ID for support investigations.