# SYNTHETIC training artifact — DELIBERATELY FLAWED draft spec (v0) for the W2 # gap-hunt exercise. The flaws are intentional; the answer key is v0-answer-key.md. # Do not fix this file — it is the exercise. openapi: 3.0.3 info: title: MTPL Policy API version: 0.9.0 description: | ⚠️ DELIBERATELY FLAWED TEACHING MATERIAL — NOT A REFERENCE SPECIFICATION. This draft is published as an exercise: it is missing security schemes, error responses, pagination, rate-limit documentation and at least one business rule, and one identifier is deliberately ambiguous. Finding those gaps is the point. Do not copy this file as a template, cite it as an example of good practice, or use it to learn OpenAPI conventions. The working specification is at https://api.cybernotes.it/mtpl/docs --- Draft API for mandatory motor third-party liability (MTPL) policies. Consumers can view coverage options, sign vehicles up for policies, and manage existing policies. servers: - url: https://api.cybernotes.it/mtpl/v1 paths: /coverage-options: get: summary: List available MTPL coverage options operationId: listCoverageOptions responses: "200": description: The list of coverage options. content: application/json: schema: type: object properties: options: type: array items: $ref: "#/components/schemas/CoverageOption" example: options: - code: MTPL-STD name: Mandatory motor liability term: P1Y /auth/token: post: summary: Obtain an access token operationId: createToken requestBody: required: true content: application/json: schema: type: object properties: clientId: type: string clientSecret: type: string responses: "200": description: A token. content: application/json: schema: type: object properties: access_token: type: string expires_in: type: integer /policies: post: summary: Create a policy for a vehicle description: Signs a vehicle up for an MTPL policy. operationId: createPolicy requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/PolicyRequest" example: vehicleId: "ABC-123" holderName: "Jane Example" responses: "201": description: Policy created. content: application/json: schema: $ref: "#/components/schemas/Policy" get: summary: List policies operationId: listPolicies responses: "200": description: Policies for the authenticated client. content: application/json: schema: type: array items: $ref: "#/components/schemas/Policy" /policies/{policyId}: get: summary: Get one policy operationId: getPolicy parameters: - name: policyId in: path required: true schema: type: string responses: "200": description: The policy. content: application/json: schema: $ref: "#/components/schemas/Policy" "404": description: Policy not found. put: summary: Update a policy operationId: updatePolicy parameters: - name: policyId in: path required: true schema: type: string requestBody: content: application/json: schema: $ref: "#/components/schemas/PolicyRequest" responses: "200": description: Updated policy. content: application/json: schema: $ref: "#/components/schemas/Policy" /policies/{policyId}/cancel: post: summary: Cancel a policy operationId: cancelPolicy parameters: - name: policyId in: path required: true schema: type: string responses: "200": description: The cancelled policy. content: application/json: schema: $ref: "#/components/schemas/Policy" components: schemas: CoverageOption: type: object properties: code: type: string name: type: string term: type: string description: Policy term as an ISO 8601 duration, e.g. P1Y. PolicyRequest: type: object required: [vehicleId, holderName] properties: vehicleId: type: string description: The vehicle identifier. example: "WVWZZZ1JZXW000001" holderName: type: string maxLength: 120 Policy: type: object properties: policyId: type: string example: "POL-2026-000123" vehicleId: type: string example: "ABC-123" holderName: type: string status: type: string enum: [active, updated, cancelled, expired] validFrom: type: string format: date validTo: type: string format: date