VPD Submission Returns - Domain API Specifications

Producer and platform OAS specifications for the VPD Submission Returns Domain API.

Structure

domain/
├── fragments/                            # Centrally-versioned YAML fragments
│   ├── headers/v1/oas.yaml               # Common headers (X-Correlation-Id, ETag, etc.)
│   ├── schemas/v1/oas.yaml               # Common schemas (Money, Address, Error, etc.)
│   ├── responses/v1/oas.yaml             # Common responses (400, 404, 500, etc.)
│   └── parameters/v1/oas.yaml            # Common parameters (pagination, sorting)
├── producer/                             # Producer-maintained OAS
│   └── vpd-submission-returns-api.yaml   # Source of truth (domain contract)
├── platform/                             # Generated platform OAS
│   └── vpd-submission-returns-api.yaml   # Published to API portal
└── tools/                                # Generation tools
    ├── generate_platform_oas.py          # OAS generator
    └── README.md                         # Tool documentation

Producer OAS (Source of Truth)

Location: producer/vpd-submission-returns-api.yaml

Purpose: Domain API contract maintained by the VPD team

Characteristics:

  • Uses $ref to common fragments (headers, schemas, responses)
  • Focuses on domain-specific logic and schemas
  • NO mention of sparse fieldsets (platform handles this automatically)
  • Clean, readable, maintainable

Example:

paths:
  /duty/vpd/submission-returns/v1:
    get:
      parameters:
        - $ref: '../fragments/headers/v1/oas.yaml#/X-Correlation-Id-Header'
        - $ref: '#/components/parameters/acknowledgementReference'
      responses:
        '200':
          headers:
            ETag:
              $ref: '../fragments/headers/v1/oas.yaml#/ETag'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EnrichedSubmission'
        '400':
          $ref: '../fragments/responses/v1/oas.yaml#/BadRequest'

Common Fragments

Location: fragments/

Purpose: Centrally-versioned, reusable YAML fragments shared across all APIs

Version Control:

  • Fragments are versioned centrally by the platform team
  • Producer and platform OAS reference fragments via $ref (NOT inlined)
  • Changes to fragments automatically propagate to all APIs
  • Ensures consistency across the API platform

Versioning:

  • Each fragment type has its own version directory (e.g., headers/v1/, headers/v2/)
  • Allows breaking changes without affecting existing APIs
  • APIs explicitly reference fragment version in $ref
  • Platform team controls fragment versioning and lifecycle

Files:

headers/v1/oas.yaml

Request and response headers:

  • X-Correlation-Id - Request tracing
  • X-Idempotency-Key - Safe retries
  • ETag - Optimistic locking
  • X-RateLimit-* - Rate limiting info

schemas/v1/oas.yaml

Common data types:

  • Money - Monetary amounts
  • Address - UK postal addresses
  • Error - Standard error format
  • Timestamp - ISO 8601 timestamps
  • PeriodKey - Period identifiers

responses/v1/oas.yaml

Standard HTTP error responses:

  • BadRequest (400)
  • Unauthorized (401)
  • Forbidden (403)
  • NotFound (404)
  • Conflict (409)
  • ValidationError (422)
  • TooManyRequests (429)
  • InternalServerError (500)
  • ServiceUnavailable (503)

parameters/v1/oas.yaml

Common query parameters:

  • page, pageSize - Pagination
  • sort - Sorting
  • fromDate, toDate - Date filtering

Note: Sparse fieldsets (fields[:resource]=...) are NOT in common parameters because they’re automatically injected by the platform for ALL GET operations.

Platform OAS (Generated)

Location: platform/vpd-submission-returns-api.yaml

Purpose: Consumer-facing specification published to API portal

Characteristics:

  • Preserves $ref to centrally-versioned fragments
  • Sparse fieldsets parameter added to GET operations
  • Platform metadata added
  • Complete documentation for consumers

Generated by:

cd tools
python generate_platform_oas.py ../producer/vpd-submission-returns-api.yaml

Sparse Fieldsets (Platform Feature)

Sparse fieldsets are a platform responsibility and work automatically for all GET operations.

Format: fields[:resourceType]=field1,field2,field3

Example:

GET /duty/vpd/submission-returns/v1?acknowledgementReference=ACK-123&fields[:submission]=acknowledgementReference,totalDutyDue,vat

How It Works

  1. Producer defines clean GET endpoints with response schemas (no mention of sparse fieldsets)
  2. Platform generator inspects response schema and extracts field names
  3. Platform gateway validates field names at runtime and filters responses
  4. Platform OAS documents available fields for consumers

Why This Design?

  • Producers don’t maintain field lists - Generated from schema automatically
  • Platform enforces consistency - Same behavior across all APIs
  • No opt-in required - Works for all GET operations by default
  • Runtime validation - Invalid fields return 400 with details

Workflow

For Producers (VPD Team)

  1. Edit producer OAS:

    vi producer/vpd-submission-returns-api.yaml
  2. Use versioned common fragments:

    $ref: '../fragments/headers/v1/oas.yaml#/ETag'
  3. Validate:

    redocly lint producer/vpd-submission-returns-api.yaml
  4. Generate platform OAS:

    cd tools
    python generate_platform_oas.py ../producer/vpd-submission-returns-api.yaml
  5. Commit both:

    git add producer/ platform/generated/
    git commit -m "Update VPD submission returns API"

For Platform Team

  1. Update common fragments:

    vi fragments/schemas/v1/oas.yaml

    For breaking changes, create new version:

    cp -r fragments/schemas/v1 fragments/schemas/v2
    vi fragments/schemas/v2/oas.yaml
  2. Test with example API:

    cd tools
    python generate_platform_oas.py ../producer/vpd-submission-returns-api.yaml
  3. Commit changes:

    git add fragments/
    git commit -m "Add new common schema: TaxReference"

Deployment

Producer OAS

  • Stored: Git repository (source of truth)
  • Used by: Producers for API design and documentation
  • Not published to external API portal

Platform OAS

  • Generated: By tools/generate_platform_oas.py
  • Stored: Git repository (platform/generated/)
  • Published: To HIP API portal for consumers
  • Used by: API consumers, integration teams, Swagger UI

Benefits

Clean Separation

  • Producers focus on domain logic
  • Platform handles infrastructure concerns
  • No duplication of common elements

Automatic Features

  • Sparse fieldsets work without producer effort
  • Rate limiting headers added automatically
  • Correlation IDs handled by platform

Maintainability

  • Common elements in one place
  • Changes to platform fragments affect all APIs
  • Producer OAS stays clean and readable

Validation

# Validate producer OAS
redocly lint producer/vpd-submission-returns-api.yaml
 
# Validate common fragments (v1)
redocly lint fragments/headers/v1/oas.yaml
redocly lint fragments/schemas/v1/oas.yaml
redocly lint fragments/responses/v1/oas.yaml
redocly lint fragments/parameters/v1/oas.yaml
 
# Generate and validate platform OAS
cd tools
python generate_platform_oas.py ../producer/vpd-submission-returns-api.yaml
redocly lint ../platform/vpd-submission-returns-api.yaml

See Also

  • Tool Documentation: tools/README.md - Detailed generator usage
  • Project Spec: ../spec.md - Feature requirements
  • Project Plan: ../plan.md - Implementation phases