# API-auditoinnin tarkistuslista

Canonical page: https://apiopscycles.com/fi/resources/api-audit-checklist

Language: fi

Entity ID: api-audit-checklist

Elinkaaripohjainen tarkistuslista, jolla varmistetaan APIn valmius suunnittelun, toimituksen, julkaisun ja vaatimustenmukaisuuden osalta määriteltyjen auditointikriteerien ja todisteiden avulla.

Category: checklist

## Outcomes

- Yhteinen ymmärrys resurssin API-auditoinnin tarkistuslista tarkoituksesta ja käytöstä
- Johdonmukainen tapa soveltaa resurssia API-auditoinnin tarkistuslista
- Asiaan liittyvien käytäntöjen parempi soveltaminen

## How to use

1. Varmista API-auditoinnin tarkistuslistan avulla, että API-design täyttää toiminnalliset ja muut kuin toiminnalliset vaatimukset, mukaan lukien tietoturva, suorituskyky ja vaatimustenmukaisuus.
2. Suorita auditointeja elinkaaren kattavuuden arvioimiseksi ja varmista, että API täyttää liiketoiminta-, suunnittelu- ja toimintastandardit.
3. Varmista, että dokumentaatio, tietoturvamallit, gateway-konfiguraatio ja lakisääteiset vaatimukset on määritelty selkeästi, validoitu ja tuettu todisteilla.

## Source content

```json
{
  "profiles": {
    "read-only": {
      "description": "API profile that is read-only and does not allow create, update, or delete operations."
    },
    "full-crud": {
      "description": "General API profile that allows create, update, and delete operations."
    }
  },
  "lifecycleStages": [
    {
      "id": "strategy",
      "title": "Strategy",
      "readinessLabel": "Strategy is Ready When...",
      "order": 1
    },
    {
      "id": "architecture",
      "title": "Architecture",
      "readinessLabel": "Architecture is Ready When...",
      "order": 2
    },
    {
      "id": "design",
      "title": "Design",
      "readinessLabel": "Design is Ready When...",
      "order": 3
    },
    {
      "id": "delivery",
      "title": "Delivery",
      "readinessLabel": "Delivery is Ready When...",
      "order": 4
    },
    {
      "id": "publishing",
      "title": "Publishing",
      "readinessLabel": "Publishing is Ready When...",
      "order": 5
    },
    {
      "id": "improving",
      "title": "Improving",
      "readinessLabel": "Improving is Ready When...",
      "order": 6
    }
  ],
  "stages": [
    {
      "id": "strategy",
      "title": "Strategy",
      "readinessLabel": "Strategy is Ready When...",
      "order": 1,
      "items": [
        {
          "id": "based-on-clear-business-needs",
          "label": "API is based on clear business needs",
          "applicableTo": [
            "read-only",
            "full-crud"
          ],
          "kind": "manual",
          "defaultStatus": "partial",
          "automationLevel": "manual",
          "primaryStage": "strategy",
          "producedByStation": [
            "api-product-strategy"
          ],
          "producedByStationCriteria": [
            "business-goals-defined",
            "market-research-done",
            "stakeholder-approval",
            "metrics-feedback-available"
          ],
          "guidelines": [
            "REST-DOMAIN-01"
          ],
          "resourceSource": [
            "apiBusinessModelCanvas",
            "apiValuePropositionCanvas"
          ],
          "expectedEvidenceTags": [
            "design-artifact",
            "documentation",
            "research"
          ],
          "expectedEvidence": [
            "specs/canvases/api-product-strategy/apiValuePropositionCanvas.empty.json",
            "specs/canvases/api-product-strategy/apiBusinessModelCanvas.empty.json"
          ]
        },
        {
          "id": "concept-items-audited",
          "label": "All concept checklist items are audited",
          "applicableTo": [
            "read-only",
            "full-crud"
          ],
          "kind": "aggregate",
          "check": {
            "type": "stageCoverage",
            "stageId": "strategy"
          },
          "automationLevel": "semi",
          "primaryStage": "strategy",
          "producedByStation": [
            "api-product-strategy",
            "api-consumer-experience"
          ],
          "producedByStationCriteria": [
            "business-goals-defined",
            "market-research-done",
            "stakeholder-approval",
            "metrics-feedback-available",
            "api-opportunity-documented",
            "api-reusability",
            "value-prop-validated",
            "consumer-segments-identified"
          ],
          "guidelines": [
            "REST-AUDIT-02"
          ],
          "resourceSource": [
            "api-audit-checklist"
          ],
          "expectedEvidenceTags": [
            "report"
          ],
          "expectedEvidence": [
            "audit/concept-review-report.json"
          ]
        }
      ]
    },
    {
      "id": "architecture",
      "title": "Architecture",
      "readinessLabel": "Architecture is Ready When...",
      "order": 2,
      "items": [
        {
          "id": "versioning-decided",
          "label": "Versioning strategy decided and supported by gateway",
          "applicableTo": [
            "read-only",
            "full-crud"
          ],
          "kind": "manual",
          "defaultStatus": "partial",
          "automationLevel": "semi",
          "primaryStage": "architecture",
          "producedByStation": [
            "api-platform-architecture",
            "api-publishing"
          ],
          "producedByStationCriteria": [
            "api-roadmap-defined",
            "api-reusability",
            "api-ready-for-publishing"
          ],
          "guidelines": [
            "REST-VERSION-01"
          ],
          "resourceSource": [
            "restCanvas",
            "contract-first-design",
            "api-versioning-best-practices",
            "apiops-CI-CD-for-apis"
          ],
          "expectedEvidenceTags": [
            "spec",
            "ci-cd",
            "gateway-config"
          ],
          "expectedEvidence": [
            "specs/openapi/api.yaml",
            "docs/api/architecture/README.md",
            "docs/api/publishing/README.md"
          ]
        },
        {
          "id": "only-via-gateway",
          "label": "Only accessible via API gateway",
          "applicableTo": [
            "read-only",
            "full-crud"
          ],
          "kind": "manual",
          "defaultStatus": "gap",
          "automationLevel": "semi",
          "primaryStage": "architecture",
          "producedByStation": [
            "api-platform-architecture",
            "api-publishing"
          ],
          "producedByStationCriteria": [
            "api-reusability",
            "api-ready-for-publishing",
            "audit-passed"
          ],
          "guidelines": [
            "REST-PUBLISH-02",
            "REST-CAPACITY-02"
          ],
          "resourceSource": [
            "businessImpactCanvas",
            "locationsCanvas",
            "api-security-best-practices",
            "data-privacy-guidelines"
          ],
          "expectedEvidenceTags": [
            "gateway-config",
            "infra-config",
            "security-config"
          ],
          "expectedEvidence": [
            "docs/api/architecture/README.md",
            "docs/api/publishing/README.md"
          ]
        },
        {
          "id": "rate-limits-enforced",
          "label": "Rate limits are enforced",
          "applicableTo": [
            "read-only",
            "full-crud"
          ],
          "kind": "manual",
          "defaultStatus": "partial",
          "automationLevel": "semi",
          "primaryStage": "architecture",
          "producedByStation": [
            "api-platform-architecture"
          ],
          "producedByStationCriteria": [
            "api-roadmap-defined",
            "api-reusability"
          ],
          "guidelines": [
            "REST-CAPACITY-01",
            "REST-OBS-01",
            "REST-SEC-04"
          ],
          "resourceSource": [
            "capacityCanvas",
            "api-security-best-practices",
            "scalable-infrastructure-best-practices",
            "api-metrics-and-analytics"
          ],
          "expectedEvidenceTags": [
            "gateway-config",
            "runtime",
            "monitoring"
          ],
          "expectedEvidence": [
            "specs/canvases/api-platform-architecture/capacityCanvas.empty.json",
            "docs/api/architecture/README.md"
          ]
        }
      ]
    },
    {
      "id": "design",
      "title": "Design",
      "readinessLabel": "Design is Ready When...",
      "order": 3,
      "items": [
        {
          "id": "endpoint-descriptions-present",
          "label": "Endpoints have business value and feature descriptions",
          "applicableTo": [
            "read-only",
            "full-crud"
          ],
          "kind": "openapi",
          "check": {
            "type": "operationDescriptions"
          },
          "automationLevel": "auto",
          "primaryStage": "design",
          "producedByStation": [
            "api-design",
            "api-consumer-experience"
          ],
          "producedByStationCriteria": [
            "design-reflects-business-value",
            "value-prop-validated",
            "api-opportunity-documented"
          ],
          "guidelines": [
            "REST-CX-01"
          ],
          "resourceSource": [
            "apiValuePropositionCanvas",
            "customerJourneyCanvas",
            "api-onboarding-best-practices",
            "contract-first-design"
          ],
          "expectedEvidenceTags": [
            "spec",
            "design-artifact"
          ],
          "expectedEvidence": [
            "specs/openapi/api.yaml",
            "specs/canvases/api-product-strategy/apiValuePropositionCanvas.empty.json"
          ]
        },
        {
          "id": "hides-raw-backend-data",
          "label": "API hides raw backend data and is designed for shared use",
          "applicableTo": [
            "read-only",
            "full-crud"
          ],
          "kind": "manual",
          "defaultStatus": "partial",
          "automationLevel": "manual",
          "primaryStage": "design",
          "producedByStation": [
            "api-design"
          ],
          "producedByStationCriteria": [
            "hide-backend-discrepancies",
            "design-reflects-business-value"
          ],
          "guidelines": [
            "REST-DOMAIN-01"
          ],
          "resourceSource": [
            "domainCanvas",
            "interactionCanvas",
            "restCanvas",
            "api-design-principles",
            "contract-first-design"
          ],
          "expectedEvidenceTags": [
            "spec",
            "design-artifact"
          ],
          "expectedEvidence": [
            "specs/canvases/api-product-strategy/domainCanvas.empty.json",
            "specs/canvases/api-design/interactionCanvas.empty.json",
            "specs/openapi/api.yaml"
          ]
        },
        {
          "id": "design-consistent",
          "label": "API design is consistent with other APIs",
          "applicableTo": [
            "read-only",
            "full-crud"
          ],
          "kind": "manual",
          "defaultStatus": "partial",
          "automationLevel": "manual",
          "primaryStage": "design",
          "producedByStation": [
            "api-design",
            "api-platform-architecture"
          ],
          "producedByStationCriteria": [
            "api-consistency",
            "architecture-patterns-validated",
            "api-reusability"
          ],
          "guidelines": [
            "REST-DOMAIN-02",
            "REST-CX-03"
          ],
          "resourceSource": [
            "restCanvas",
            "api-design-principles",
            "api-audit-checklist"
          ],
          "expectedEvidenceTags": [
            "documentation",
            "design-artifact"
          ],
          "expectedEvidence": [
            "specs/canvases/api-design/restCanvas.empty.json",
            "docs/api/design/README.md"
          ]
        },
        {
          "id": "descriptive-english-naming",
          "label": "Data and attribute naming uses descriptive English",
          "applicableTo": [
            "read-only",
            "full-crud"
          ],
          "kind": "openapi",
          "check": {
            "type": "fieldNamesDescriptive"
          },
          "automationLevel": "auto",
          "primaryStage": "design",
          "producedByStation": [
            "api-design"
          ],
          "producedByStationCriteria": [
            "api-consistency"
          ],
          "guidelines": [
            "REST-NAMING-01"
          ],
          "resourceSource": [
            "domainCanvas",
            "restCanvas",
            "api-design-principles",
            "contract-first-design"
          ],
          "expectedEvidenceTags": [
            "spec"
          ],
          "expectedEvidence": [
            "specs/openapi/api.yaml"
          ]
        },
        {
          "id": "mandatory-fields-specified",
          "label": "Mandatory fields are specified",
          "applicableTo": [
            "read-only",
            "full-crud"
          ],
          "kind": "openapi",
          "check": {
            "type": "requiredFieldsPresent"
          },
          "automationLevel": "auto",
          "primaryStage": "design",
          "producedByStation": [
            "api-design"
          ],
          "producedByStationCriteria": [
            "architecture-patterns-validated",
            "api-consistency"
          ],
          "guidelines": [
            "REST-VALIDATION-01"
          ],
          "resourceSource": [
            "domainCanvas",
            "contract-first-design"
          ],
          "expectedEvidenceTags": [
            "spec",
            "contract"
          ],
          "expectedEvidence": [
            "specs/openapi/api.yaml"
          ]
        },
        {
          "id": "dates-use-iso",
          "label": "Dates use ISO format with timezone",
          "applicableTo": [
            "read-only",
            "full-crud"
          ],
          "kind": "openapi",
          "check": {
            "type": "dateFormatTimezone"
          },
          "automationLevel": "auto",
          "primaryStage": "design",
          "producedByStation": [
            "api-design"
          ],
          "producedByStationCriteria": [
            "api-consistency"
          ],
          "guidelines": [
            "REST-DATA-01"
          ],
          "resourceSource": [
            "restCanvas",
            "api-design-principles",
            "contract-first-design"
          ],
          "expectedEvidenceTags": [
            "spec"
          ],
          "expectedEvidence": [
            "specs/openapi/api.yaml"
          ]
        },
        {
          "id": "general-data-uses-standard-values",
          "label": "General data uses standard values",
          "applicableTo": [
            "read-only",
            "full-crud"
          ],
          "kind": "openapi",
          "check": {
            "type": "standardizedEnumsOrPatterns"
          },
          "automationLevel": "auto",
          "primaryStage": "design",
          "producedByStation": [
            "api-design"
          ],
          "producedByStationCriteria": [
            "api-consistency",
            "design-reflects-business-value"
          ],
          "guidelines": [
            "REST-DATA-02"
          ],
          "resourceSource": [
            "domainCanvas",
            "restCanvas",
            "api-design-principles",
            "contract-first-design"
          ],
          "expectedEvidenceTags": [
            "spec"
          ],
          "expectedEvidence": [
            "specs/openapi/api.yaml"
          ]
        },
        {
          "id": "field-names-avoid-acronyms",
          "label": "Field names avoid acronyms and use full words",
          "applicableTo": [
            "read-only",
            "full-crud"
          ],
          "kind": "openapi",
          "check": {
            "type": "avoidAcronyms"
          },
          "automationLevel": "auto",
          "primaryStage": "design",
          "producedByStation": [
            "api-design"
          ],
          "producedByStationCriteria": [
            "api-consistency"
          ],
          "guidelines": [
            "REST-NAMING-02"
          ],
          "resourceSource": [
            "domainCanvas",
            "restCanvas",
            "api-design-principles",
            "contract-first-design"
          ],
          "expectedEvidenceTags": [
            "spec"
          ],
          "expectedEvidence": [
            "specs/openapi/api.yaml"
          ]
        },
        {
          "id": "create-returns-identifiers",
          "label": "Creating new resources returns identifiers",
          "applicableTo": [
            "full-crud"
          ],
          "kind": "n/a",
          "defaultStatus": "na",
          "reason": "This profile is read-only and does not create resources.",
          "automationLevel": "manual",
          "primaryStage": "design",
          "producedByStation": [
            "api-design",
            "api-consumer-experience"
          ],
          "producedByStationCriteria": [
            "design-reflects-business-value",
            "api-consistency",
            "value-prop-validated"
          ],
          "guidelines": [
            "REST-RESP-201-01"
          ],
          "resourceSource": [
            "restCanvas",
            "api-onboarding-best-practices",
            "contract-first-design"
          ],
          "expectedEvidenceTags": [
            "spec"
          ],
          "expectedEvidence": [
            "specs/openapi/api.yaml"
          ]
        },
        {
          "id": "paths-max-two-resources",
          "label": "Endpoint paths contain max two resources or sub-resources",
          "applicableTo": [
            "read-only",
            "full-crud"
          ],
          "kind": "openapi",
          "check": {
            "type": "pathDepthMax",
            "maxDepth": 2
          },
          "automationLevel": "auto",
          "primaryStage": "design",
          "producedByStation": [
            "api-design"
          ],
          "producedByStationCriteria": [
            "api-consistency"
          ],
          "guidelines": [
            "REST-PATH-01"
          ],
          "resourceSource": [
            "restCanvas",
            "api-design-principles",
            "contract-first-design"
          ],
          "expectedEvidenceTags": [
            "spec"
          ],
          "expectedEvidence": [
            "specs/openapi/api.yaml"
          ]
        },
        {
          "id": "examples-present",
          "label": "Endpoints and attributes include examples",
          "applicableTo": [
            "read-only",
            "full-crud"
          ],
          "kind": "openapi",
          "check": {
            "type": "examplesPresent"
          },
          "automationLevel": "auto",
          "primaryStage": "design",
          "producedByStation": [
            "api-design",
            "api-consumer-experience"
          ],
          "producedByStationCriteria": [
            "design-reflects-business-value",
            "value-prop-validated"
          ],
          "guidelines": [
            "REST-CX-02"
          ],
          "resourceSource": [
            "api-onboarding-best-practices",
            "restCanvas",
            "contract-first-design"
          ],
          "expectedEvidenceTags": [
            "spec"
          ],
          "expectedEvidence": [
            "specs/openapi/api.yaml"
          ]
        },
        {
          "id": "post-for-create-update",
          "label": "POST is used for create or update",
          "applicableTo": [
            "full-crud"
          ],
          "kind": "n/a",
          "defaultStatus": "na",
          "reason": "Read-only profile does not expose create or update operations.",
          "automationLevel": "manual",
          "primaryStage": "design",
          "producedByStation": [
            "api-design"
          ],
          "producedByStationCriteria": [
            "api-consistency",
            "design-reflects-business-value"
          ],
          "guidelines": [
            "REST-HTTP-POST-01",
            "REST-HTTP-PUT-01"
          ],
          "resourceSource": [
            "restCanvas",
            "api-design-principles",
            "contract-first-design"
          ],
          "expectedEvidenceTags": [
            "spec"
          ],
          "expectedEvidence": [
            "specs/openapi/api.yaml"
          ]
        },
        {
          "id": "delete-for-remove",
          "label": "DELETE is used to remove resources",
          "applicableTo": [
            "full-crud"
          ],
          "kind": "n/a",
          "defaultStatus": "na",
          "reason": "Read-only profile does not expose delete operations.",
          "automationLevel": "manual",
          "primaryStage": "design",
          "producedByStation": [
            "api-design"
          ],
          "producedByStationCriteria": [
            "api-consistency"
          ],
          "guidelines": [
            "REST-HTTP-DELETE-01"
          ],
          "resourceSource": [
            "restCanvas",
            "api-design-principles",
            "contract-first-design"
          ],
          "expectedEvidenceTags": [
            "spec"
          ],
          "expectedEvidence": [
            "specs/openapi/api.yaml"
          ]
        },
        {
          "id": "get-no-request-body",
          "label": "GET has no request body and returns content",
          "applicableTo": [
            "read-only",
            "full-crud"
          ],
          "kind": "openapi",
          "check": {
            "type": "getNoRequestBody"
          },
          "automationLevel": "auto",
          "primaryStage": "design",
          "producedByStation": [
            "api-design"
          ],
          "producedByStationCriteria": [
            "api-consistency"
          ],
          "guidelines": [
            "REST-HTTP-GET-01",
            "REST-RESP-200-01"
          ],
          "resourceSource": [
            "restCanvas",
            "api-design-principles",
            "contract-first-design"
          ],
          "expectedEvidenceTags": [
            "spec"
          ],
          "expectedEvidence": [
            "specs/openapi/api.yaml"
          ]
        },
        {
          "id": "get-empty-returns-204",
          "label": "GET returns 204 if response body is empty",
          "applicableTo": [
            "read-only",
            "full-crud"
          ],
          "kind": "n/a",
          "defaultStatus": "na",
          "reason": "The current contract returns content for all GET operations.",
          "automationLevel": "manual",
          "primaryStage": "design",
          "producedByStation": [
            "api-design",
            "api-consumer-experience"
          ],
          "producedByStationCriteria": [
            "api-consistency",
            "value-prop-validated"
          ],
          "guidelines": [
            "REST-RESP-204-02"
          ],
          "resourceSource": [
            "restCanvas",
            "api-onboarding-best-practices",
            "contract-first-design"
          ],
          "expectedEvidenceTags": [
            "spec"
          ],
          "expectedEvidence": [
            "specs/openapi/api.yaml"
          ]
        },
        {
          "id": "post-returns-200",
          "label": "POST returns 200 OK when updating",
          "applicableTo": [
            "full-crud"
          ],
          "kind": "n/a",
          "defaultStatus": "na",
          "reason": "Read-only profile does not expose POST updates.",
          "automationLevel": "manual",
          "primaryStage": "design",
          "producedByStation": [
            "api-design",
            "api-consumer-experience"
          ],
          "producedByStationCriteria": [
            "api-consistency",
            "value-prop-validated"
          ],
          "guidelines": [
            "REST-RESP-200-01"
          ],
          "resourceSource": [
            "restCanvas",
            "api-onboarding-best-practices",
            "contract-first-design"
          ],
          "expectedEvidenceTags": [
            "spec"
          ],
          "expectedEvidence": [
            "specs/openapi/api.yaml"
          ]
        },
        {
          "id": "post-returns-201",
          "label": "POST returns 201 Created with ID on create",
          "applicableTo": [
            "full-crud"
          ],
          "kind": "n/a",
          "defaultStatus": "na",
          "reason": "Read-only profile does not expose POST creates.",
          "automationLevel": "manual",
          "primaryStage": "design",
          "producedByStation": [
            "api-design",
            "api-consumer-experience"
          ],
          "producedByStationCriteria": [
            "api-consistency",
            "value-prop-validated"
          ],
          "guidelines": [
            "REST-RESP-201-01"
          ],
          "resourceSource": [
            "restCanvas",
            "api-onboarding-best-practices",
            "contract-first-design"
          ],
          "expectedEvidenceTags": [
            "spec"
          ],
          "expectedEvidence": [
            "specs/openapi/api.yaml"
          ]
        },
        {
          "id": "delete-returns-204",
          "label": "DELETE returns 204 on success",
          "applicableTo": [
            "full-crud"
          ],
          "kind": "n/a",
          "defaultStatus": "na",
          "reason": "Read-only profile does not expose DELETE operations.",
          "automationLevel": "manual",
          "primaryStage": "design",
          "producedByStation": [
            "api-design",
            "api-consumer-experience"
          ],
          "producedByStationCriteria": [
            "api-consistency",
            "value-prop-validated"
          ],
          "guidelines": [
            "REST-RESP-204-01"
          ],
          "resourceSource": [
            "restCanvas",
            "api-onboarding-best-practices",
            "contract-first-design"
          ],
          "expectedEvidenceTags": [
            "spec"
          ],
          "expectedEvidence": [
            "specs/openapi/api.yaml"
          ]
        },
        {
          "id": "400-errors-specific",
          "label": "400 errors provide specific error information",
          "applicableTo": [
            "read-only",
            "full-crud"
          ],
          "kind": "openapi",
          "check": {
            "type": "errorResponsesSpecific"
          },
          "automationLevel": "auto",
          "primaryStage": "design",
          "producedByStation": [
            "api-design",
            "api-consumer-experience"
          ],
          "producedByStationCriteria": [
            "design-reflects-business-value",
            "api-consistency",
            "value-prop-validated"
          ],
          "guidelines": [
            "REST-ERROR-400-01"
          ],
          "resourceSource": [
            "api-onboarding-best-practices",
            "restCanvas",
            "api-audit-checklist",
            "contract-first-design"
          ],
          "expectedEvidenceTags": [
            "spec"
          ],
          "expectedEvidence": [
            "specs/openapi/api.yaml"
          ]
        },
        {
          "id": "401-unauthorized",
          "label": "401 Unauthorized for wrong credentials",
          "applicableTo": [
            "read-only",
            "full-crud"
          ],
          "kind": "n/a",
          "defaultStatus": "na",
          "reason": "The current public storefront contract is intentionally unauthenticated.",
          "automationLevel": "semi",
          "primaryStage": "design",
          "producedByStation": [
            "api-design",
            "api-publishing"
          ],
          "producedByStationCriteria": [
            "api-consistency",
            "api-ready-for-publishing"
          ],
          "guidelines": [
            "REST-ERROR-401-01",
            "REST-SEC-01",
            "REST-SEC-03"
          ],
          "resourceSource": [
            "api-security-best-practices",
            "data-privacy-guidelines",
            "contract-first-design"
          ],
          "expectedEvidenceTags": [
            "spec",
            "security-config",
            "gateway-config"
          ],
          "expectedEvidence": [
            "specs/openapi/api.yaml"
          ]
        },
        {
          "id": "403-forbidden",
          "label": "403 Forbidden for unauthorized operations",
          "applicableTo": [
            "read-only",
            "full-crud"
          ],
          "kind": "n/a",
          "defaultStatus": "na",
          "reason": "The current profile is public read-only and exposes no unauthorized operations.",
          "automationLevel": "semi",
          "primaryStage": "design",
          "producedByStation": [
            "api-design",
            "api-publishing"
          ],
          "producedByStationCriteria": [
            "api-consistency",
            "api-ready-for-publishing"
          ],
          "guidelines": [
            "REST-ERROR-403-01",
            "REST-SEC-03"
          ],
          "resourceSource": [
            "api-security-best-practices",
            "data-privacy-guidelines",
            "contract-first-design"
          ],
          "expectedEvidenceTags": [
            "spec",
            "security-config",
            "gateway-config"
          ],
          "expectedEvidence": [
            "specs/openapi/api.yaml"
          ]
        },
        {
          "id": "spec-contains-schemas",
          "label": "Spec contains request and response schema",
          "applicableTo": [
            "read-only",
            "full-crud"
          ],
          "kind": "openapi",
          "check": {
            "type": "schemasPresent"
          },
          "automationLevel": "auto",
          "primaryStage": "design",
          "producedByStation": [
            "api-design"
          ],
          "producedByStationCriteria": [
            "architecture-patterns-validated",
            "api-consistency"
          ],
          "guidelines": [
            "REST-CONTRACT-01"
          ],
          "resourceSource": [
            "contract-first-design",
            "restCanvas"
          ],
          "expectedEvidenceTags": [
            "spec",
            "contract"
          ],
          "expectedEvidence": [
            "specs/openapi/api.yaml"
          ]
        },
        {
          "id": "pseudo-identifiers",
          "label": "UUIDs or pseudo-identifiers instead of DB IDs",
          "applicableTo": [
            "read-only",
            "full-crud"
          ],
          "kind": "openapi",
          "check": {
            "type": "opaqueIdentifiers"
          },
          "automationLevel": "auto",
          "primaryStage": "design",
          "producedByStation": [
            "api-design"
          ],
          "producedByStationCriteria": [
            "hide-backend-discrepancies",
            "api-consistency"
          ],
          "guidelines": [
            "REST-SEC-07"
          ],
          "resourceSource": [
            "domainCanvas",
            "contract-first-design",
            "api-security-best-practices"
          ],
          "expectedEvidenceTags": [
            "spec"
          ],
          "expectedEvidence": [
            "specs/openapi/api.yaml"
          ]
        },
        {
          "id": "no-sensitive-data-in-urls",
          "label": "No sensitive data in URLs",
          "applicableTo": [
            "read-only",
            "full-crud"
          ],
          "kind": "openapi",
          "check": {
            "type": "noSensitiveDataInPaths"
          },
          "automationLevel": "auto",
          "primaryStage": "design",
          "producedByStation": [
            "api-design"
          ],
          "producedByStationCriteria": [
            "hide-backend-discrepancies",
            "api-consistency"
          ],
          "guidelines": [
            "REST-SEC-06",
            "REST-SEC-04"
          ],
          "resourceSource": [
            "restCanvas",
            "contract-first-design",
            "api-security-best-practices",
            "data-privacy-guidelines"
          ],
          "expectedEvidenceTags": [
            "spec"
          ],
          "expectedEvidence": [
            "specs/openapi/api.yaml"
          ]
        },
        {
          "id": "http-methods-match-resources",
          "label": "HTTP methods only for intended resources",
          "applicableTo": [
            "read-only",
            "full-crud"
          ],
          "kind": "openapi",
          "check": {
            "type": "methodResourceConsistency"
          },
          "automationLevel": "auto",
          "primaryStage": "design",
          "producedByStation": [
            "api-design"
          ],
          "producedByStationCriteria": [
            "api-consistency"
          ],
          "guidelines": [
            "REST-HTTP-GET-01",
            "REST-HTTP-POST-01",
            "REST-HTTP-PUT-01",
            "REST-HTTP-DELETE-01"
          ],
          "resourceSource": [
            "restCanvas",
            "api-design-principles",
            "contract-first-design"
          ],
          "expectedEvidenceTags": [
            "spec"
          ],
          "expectedEvidence": [
            "specs/openapi/api.yaml"
          ]
        }
      ]
    },
    {
      "id": "delivery",
      "title": "Delivery",
      "readinessLabel": "Delivery is Ready When...",
      "order": 4,
      "items": [
        {
          "id": "design-items-audited",
          "label": "All prototype and design items are audited",
          "applicableTo": [
            "read-only",
            "full-crud"
          ],
          "kind": "aggregate",
          "check": {
            "type": "stageCoverage",
            "stageId": "design"
          },
          "automationLevel": "semi",
          "primaryStage": "delivery",
          "producedByStation": [
            "api-design",
            "api-delivery"
          ],
          "producedByStationCriteria": [
            "architecture-patterns-validated",
            "design-reflects-business-value",
            "api-consistency"
          ],
          "guidelines": [
            "REST-AUDIT-02"
          ],
          "resourceSource": [
            "api-audit-checklist"
          ],
          "expectedEvidenceTags": [
            "report"
          ],
          "expectedEvidence": [
            "audit/production-readiness-review.json"
          ]
        },
        {
          "id": "spec-validated-on-change",
          "label": "Spec validated on every change",
          "applicableTo": [
            "read-only",
            "full-crud"
          ],
          "kind": "openapi",
          "check": {
            "type": "validationWorkflowPresent"
          },
          "automationLevel": "auto",
          "primaryStage": "delivery",
          "producedByStation": [
            "api-delivery"
          ],
          "producedByStationCriteria": [
            "architecture-patterns-validated",
            "api-consistency"
          ],
          "guidelines": [
            "REST-AUDIT-01"
          ],
          "resourceSource": [
            "api-audit-checklist",
            "contract-first-design",
            "apiops-CI-CD-for-apis",
            "api-testing-best-practices"
          ],
          "expectedEvidenceTags": [
            "ci-cd",
            "spec",
            "test"
          ],
          "expectedEvidence": [
            ".github/workflows/openapi-lint.yml",
            "specs/openapi/api.yaml"
          ]
        },
        {
          "id": "schema-and-examples-pass",
          "label": "Schema and examples pass validation",
          "applicableTo": [
            "read-only",
            "full-crud"
          ],
          "kind": "openapi",
          "check": {
            "type": "examplesPassValidation"
          },
          "automationLevel": "auto",
          "primaryStage": "delivery",
          "producedByStation": [
            "api-delivery",
            "api-design"
          ],
          "producedByStationCriteria": [
            "api-consistency",
            "architecture-patterns-validated",
            "api-contract-tested"
          ],
          "guidelines": [
            "REST-AUDIT-01",
            "REST-CONTRACT-01"
          ],
          "resourceSource": [
            "contract-first-design",
            "api-audit-checklist",
            "api-testing-best-practices"
          ],
          "expectedEvidenceTags": [
            "spec",
            "test"
          ],
          "expectedEvidence": [
            "specs/openapi/api.yaml"
          ]
        },
        {
          "id": "uses-https",
          "label": "Uses HTTPS or encrypted protocols",
          "applicableTo": [
            "read-only",
            "full-crud"
          ],
          "kind": "manual",
          "defaultStatus": "gap",
          "automationLevel": "semi",
          "primaryStage": "delivery",
          "producedByStation": [
            "api-delivery",
            "api-publishing"
          ],
          "producedByStationCriteria": [
            "architecture-patterns-validated",
            "api-ready-for-publishing"
          ],
          "guidelines": [
            "REST-SEC-05"
          ],
          "resourceSource": [
            "api-security-best-practices",
            "data-privacy-guidelines",
            "api-compliance-best-practices"
          ],
          "expectedEvidenceTags": [
            "security-config",
            "gateway-config"
          ],
          "expectedEvidence": [
            "docs/api/delivery/README.md",
            "docs/api/publishing/README.md"
          ]
        },
        {
          "id": "auth-protection",
          "label": "Endpoints protected by authentication",
          "applicableTo": [
            "full-crud"
          ],
          "kind": "n/a",
          "defaultStatus": "na",
          "reason": "This profile is intentionally public read-only.",
          "automationLevel": "semi",
          "primaryStage": "delivery",
          "producedByStation": [
            "api-delivery",
            "api-publishing"
          ],
          "producedByStationCriteria": [
            "architecture-patterns-validated",
            "api-ready-for-publishing"
          ],
          "guidelines": [
            "REST-SEC-01",
            "REST-SEC-04"
          ],
          "resourceSource": [
            "api-security-best-practices",
            "data-privacy-guidelines",
            "api-compliance-best-practices"
          ],
          "expectedEvidenceTags": [
            "security-config",
            "gateway-config",
            "spec"
          ],
          "expectedEvidence": [
            "docs/api/delivery/README.md",
            "docs/api/publishing/README.md",
            "specs/openapi/api.yaml"
          ]
        },
        {
          "id": "token-auth",
          "label": "Token-based authentication",
          "applicableTo": [
            "full-crud"
          ],
          "kind": "n/a",
          "defaultStatus": "na",
          "reason": "This profile is intentionally public read-only.",
          "automationLevel": "semi",
          "primaryStage": "delivery",
          "producedByStation": [
            "api-delivery",
            "api-publishing"
          ],
          "producedByStationCriteria": [
            "architecture-patterns-validated",
            "api-ready-for-publishing"
          ],
          "guidelines": [
            "REST-SEC-02"
          ],
          "resourceSource": [
            "api-security-best-practices",
            "data-privacy-guidelines",
            "api-compliance-best-practices"
          ],
          "expectedEvidenceTags": [
            "security-config",
            "spec"
          ],
          "expectedEvidence": [
            "docs/api/delivery/README.md",
            "docs/api/publishing/README.md",
            "specs/openapi/api.yaml"
          ]
        },
        {
          "id": "csrf-protection",
          "label": "Protected against CSRF",
          "applicableTo": [
            "full-crud"
          ],
          "kind": "n/a",
          "defaultStatus": "na",
          "reason": "This profile is intentionally public read-only.",
          "automationLevel": "semi",
          "primaryStage": "delivery",
          "producedByStation": [
            "api-delivery"
          ],
          "producedByStationCriteria": [
            "architecture-patterns-validated",
            "api-consistency"
          ],
          "guidelines": [
            "REST-SEC-08"
          ],
          "resourceSource": [
            "api-security-best-practices",
            "data-privacy-guidelines",
            "api-development-best-practices"
          ],
          "expectedEvidenceTags": [
            "security-config",
            "code"
          ],
          "expectedEvidence": [
            "docs/api/delivery/README.md",
            "specs/openapi/api.yaml"
          ]
        },
        {
          "id": "inputs-auto-validated",
          "label": "Inputs auto-validated by framework",
          "applicableTo": [
            "read-only",
            "full-crud"
          ],
          "kind": "manual",
          "defaultStatus": "partial",
          "automationLevel": "semi",
          "primaryStage": "delivery",
          "producedByStation": [
            "api-delivery"
          ],
          "producedByStationCriteria": [
            "architecture-patterns-validated",
            "api-consistency"
          ],
          "guidelines": [
            "REST-VALIDATION-01"
          ],
          "resourceSource": [
            "api-development-best-practices",
            "contract-first-design",
            "api-testing-best-practices"
          ],
          "expectedEvidenceTags": [
            "code",
            "test",
            "spec"
          ],
          "expectedEvidence": [
            "specs/openapi/api.yaml",
            "docs/api/delivery/README.md"
          ]
        },
        {
          "id": "outputs-auto-escaped",
          "label": "Outputs auto-escaped by framework",
          "applicableTo": [
            "read-only",
            "full-crud"
          ],
          "kind": "n/a",
          "defaultStatus": "na",
          "reason": "JSON APIs do not typically require output escaping in the same way as HTML rendering.",
          "automationLevel": "manual",
          "primaryStage": "delivery",
          "producedByStation": [
            "api-delivery"
          ],
          "producedByStationCriteria": [
            "architecture-patterns-validated",
            "api-consistency"
          ],
          "guidelines": [
            "REST-SEC-04"
          ],
          "resourceSource": [
            "api-development-best-practices",
            "api-security-best-practices",
            "data-privacy-guidelines"
          ],
          "expectedEvidenceTags": [
            "code"
          ],
          "expectedEvidence": [
            "docs/api/delivery/README.md"
          ]
        },
        {
          "id": "encryption-in-transit",
          "label": "Encryption for data in transit and storage",
          "applicableTo": [
            "read-only",
            "full-crud"
          ],
          "kind": "manual",
          "defaultStatus": "gap",
          "automationLevel": "semi",
          "primaryStage": "delivery",
          "producedByStation": [
            "api-delivery",
            "api-publishing"
          ],
          "producedByStationCriteria": [
            "architecture-patterns-validated",
            "api-ready-for-publishing",
            "audit-passed"
          ],
          "guidelines": [
            "REST-SEC-05"
          ],
          "resourceSource": [
            "api-security-best-practices",
            "data-privacy-guidelines",
            "api-compliance-best-practices",
            "api-metrics-and-analytics"
          ],
          "expectedEvidenceTags": [
            "security-config",
            "infra-config",
            "documentation"
          ],
          "expectedEvidence": [
            "docs/api/delivery/README.md",
            "docs/api/publishing/README.md"
          ]
        },
        {
          "id": "message-integrity",
          "label": "Message integrity implemented",
          "applicableTo": [
            "read-only",
            "full-crud"
          ],
          "kind": "manual",
          "defaultStatus": "gap",
          "automationLevel": "semi",
          "primaryStage": "delivery",
          "producedByStation": [
            "api-delivery"
          ],
          "producedByStationCriteria": [
            "architecture-patterns-validated",
            "api-consistency"
          ],
          "guidelines": [
            "REST-OBS-01",
            "REST-SEC-04"
          ],
          "resourceSource": [
            "api-security-best-practices",
            "api-compliance-best-practices",
            "api-metrics-and-analytics"
          ],
          "expectedEvidenceTags": [
            "security-config",
            "monitoring",
            "documentation"
          ],
          "expectedEvidence": [
            "docs/api/delivery/README.md",
            "docs/api/architecture/README.md"
          ]
        }
      ]
    },
    {
      "id": "publishing",
      "title": "Publishing",
      "readinessLabel": "Publishing is Ready When...",
      "order": 5,
      "items": [
        {
          "id": "published-via-api-management",
          "label": "Published via API management",
          "applicableTo": [
            "read-only",
            "full-crud"
          ],
          "kind": "manual",
          "defaultStatus": "gap",
          "automationLevel": "semi",
          "primaryStage": "publishing",
          "producedByStation": [
            "api-publishing"
          ],
          "producedByStationCriteria": [
            "api-ready-for-publishing",
            "audit-passed"
          ],
          "guidelines": [
            "REST-PUBLISH-01"
          ],
          "resourceSource": [
            "apiops-CI-CD-for-apis",
            "api-onboarding-best-practices",
            "api-audit-checklist"
          ],
          "expectedEvidenceTags": [
            "gateway-config",
            "ci-cd",
            "documentation"
          ],
          "expectedEvidence": [
            ".github/workflows/openapi-lint.yml",
            "docs/api/publishing/README.md"
          ]
        },
        {
          "id": "visible-in-dev-portal",
          "label": "Visible in developer portal",
          "applicableTo": [
            "read-only",
            "full-crud"
          ],
          "kind": "manual",
          "defaultStatus": "gap",
          "automationLevel": "semi",
          "primaryStage": "publishing",
          "producedByStation": [
            "api-publishing"
          ],
          "producedByStationCriteria": [
            "api-documentation-ready",
            "api-ready-for-publishing"
          ],
          "guidelines": [
            "REST-PUBLISH-03"
          ],
          "resourceSource": [
            "api-onboarding-best-practices",
            "api-community-engagement-strategies"
          ],
          "expectedEvidenceTags": [
            "documentation",
            "runtime"
          ],
          "expectedEvidence": [
            "docs/api/publishing/README.md"
          ]
        },
        {
          "id": "docs-auto-generated",
          "label": "Docs auto-generated from spec and schema",
          "applicableTo": [
            "read-only",
            "full-crud"
          ],
          "kind": "manual",
          "defaultStatus": "partial",
          "automationLevel": "semi",
          "primaryStage": "publishing",
          "producedByStation": [
            "api-publishing",
            "api-delivery"
          ],
          "producedByStationCriteria": [
            "api-documentation-ready",
            "api-ready-for-publishing",
            "api-consistency"
          ],
          "guidelines": [
            "REST-CONTRACT-02",
            "REST-PUBLISH-03"
          ],
          "resourceSource": [
            "contract-first-design",
            "apiops-CI-CD-for-apis",
            "api-onboarding-best-practices"
          ],
          "expectedEvidenceTags": [
            "spec",
            "documentation",
            "ci-cd"
          ],
          "expectedEvidence": [
            "specs/openapi/api.yaml",
            "docs/api/publishing/README.md",
            "docs/api/audit/design-audit.read-only.md"
          ]
        },
        {
          "id": "spec-auto-updated",
          "label": "Spec auto-updated to gateway and dev portal",
          "applicableTo": [
            "read-only",
            "full-crud"
          ],
          "kind": "manual",
          "defaultStatus": "gap",
          "automationLevel": "semi",
          "primaryStage": "publishing",
          "producedByStation": [
            "api-publishing",
            "api-delivery"
          ],
          "producedByStationCriteria": [
            "api-ready-for-publishing",
            "audit-passed",
            "api-consistency"
          ],
          "guidelines": [
            "REST-CONTRACT-02"
          ],
          "resourceSource": [
            "apiops-CI-CD-for-apis",
            "contract-first-design",
            "api-onboarding-best-practices"
          ],
          "expectedEvidenceTags": [
            "ci-cd",
            "gateway-config",
            "documentation"
          ],
          "expectedEvidence": [
            ".github/workflows/openapi-lint.yml",
            "docs/api/publishing/README.md",
            "specs/openapi/api.yaml"
          ]
        },
        {
          "id": "official-domain",
          "label": "Published under official organization domain",
          "applicableTo": [
            "read-only",
            "full-crud"
          ],
          "kind": "manual",
          "defaultStatus": "gap",
          "automationLevel": "semi",
          "primaryStage": "publishing",
          "producedByStation": [
            "api-publishing"
          ],
          "producedByStationCriteria": [
            "api-ready-for-publishing",
            "audit-passed"
          ],
          "guidelines": [
            "REST-PUBLISH-04"
          ],
          "resourceSource": [
            "api-onboarding-best-practices",
            "api-audit-checklist"
          ],
          "expectedEvidenceTags": [
            "documentation",
            "runtime"
          ],
          "expectedEvidence": [
            "docs/api/publishing/README.md"
          ]
        }
      ]
    },
    {
      "id": "improving",
      "title": "Improving",
      "readinessLabel": "Improving is Ready When...",
      "order": 6,
      "items": []
    }
  ],
  "guidelines": [
    {
      "id": "REST-CONTRACT-01",
      "priority": "MUST",
      "category": "contract-governance",
      "requirement": "The REST API MUST implement endpoints, parameters, request bodies, response bodies, and error responses as defined in the validated OpenAPI contract.",
      "relatedAuditItems": [
        "spec-contains-schemas",
        "schema-and-examples-pass"
      ]
    },
    {
      "id": "REST-CONTRACT-02",
      "priority": "MUST",
      "category": "contract-governance",
      "requirement": "The REST API MUST keep the implementation, published OpenAPI description, gateway configuration, and developer portal documentation aligned on every change.",
      "relatedAuditItems": [
        "docs-auto-generated",
        "spec-auto-updated",
        "spec-validated-on-change"
      ]
    },
    {
      "id": "REST-VALIDATION-01",
      "priority": "MUST",
      "category": "contract-governance",
      "requirement": "The REST API MUST validate path parameters, query parameters, headers, and JSON request bodies against the OpenAPI schema before business processing.",
      "relatedAuditItems": [
        "mandatory-fields-specified",
        "400-errors-specific",
        "inputs-auto-validated"
      ]
    },
    {
      "id": "REST-DOMAIN-01",
      "priority": "MUST",
      "category": "domain-modeling",
      "requirement": "The REST API MUST expose business-oriented resources and attributes rather than raw backend tables, internal service payloads, or system-specific field names.",
      "relatedAuditItems": [
        "based-on-clear-business-needs",
        "hides-raw-backend-data"
      ]
    },
    {
      "id": "REST-DOMAIN-02",
      "priority": "MUST",
      "category": "domain-modeling",
      "requirement": "The REST API MUST preserve validated meanings of entities, attributes, statuses, and source-of-truth rules across all endpoints and operations.",
      "relatedAuditItems": [
        "design-consistent",
        "general-data-uses-standard-values"
      ]
    },
    {
      "id": "REST-NAMING-01",
      "priority": "MUST",
      "category": "domain-modeling",
      "requirement": "The REST API MUST use descriptive English names for resources and attributes.",
      "relatedAuditItems": [
        "descriptive-english-naming"
      ]
    },
    {
      "id": "REST-NAMING-02",
      "priority": "MUST",
      "category": "domain-modeling",
      "requirement": "The REST API MUST avoid unexplained acronyms in public field and resource names.",
      "relatedAuditItems": [
        "field-names-avoid-acronyms"
      ]
    },
    {
      "id": "REST-DATA-01",
      "priority": "MUST",
      "category": "domain-modeling",
      "requirement": "The REST API MUST use ISO date-time values with timezone information where dates are exposed.",
      "relatedAuditItems": [
        "dates-use-iso"
      ]
    },
    {
      "id": "REST-DATA-02",
      "priority": "SHOULD",
      "category": "domain-modeling",
      "requirement": "The REST API SHOULD use standard codes, controlled vocabularies, and standardized value sets where applicable.",
      "relatedAuditItems": [
        "general-data-uses-standard-values"
      ]
    },
    {
      "id": "REST-CX-01",
      "priority": "MUST",
      "category": "consumer-experience",
      "requirement": "The REST API MUST describe the business value and feature intent of each endpoint or capability.",
      "relatedAuditItems": [
        "endpoint-descriptions-present"
      ]
    },
    {
      "id": "REST-CX-02",
      "priority": "MUST",
      "category": "consumer-experience",
      "requirement": "The REST API MUST include examples for endpoints, request bodies, response bodies, and key attributes.",
      "relatedAuditItems": [
        "examples-present"
      ]
    },
    {
      "id": "REST-CX-03",
      "priority": "SHOULD",
      "category": "consumer-experience",
      "requirement": "The REST API SHOULD use consistent pagination, filtering, sorting, and response conventions across resources.",
      "relatedAuditItems": [
        "design-consistent"
      ]
    },
    {
      "id": "REST-HTTP-GET-01",
      "priority": "MUST",
      "category": "http-semantics",
      "requirement": "The REST API MUST use GET for safe read-only operations and MUST NOT define a request body for GET operations.",
      "relatedAuditItems": [
        "get-no-request-body",
        "http-methods-match-resources"
      ]
    },
    {
      "id": "REST-HTTP-POST-01",
      "priority": "MUST",
      "category": "http-semantics",
      "requirement": "The REST API MUST use POST for resource creation and other non-idempotent operations.",
      "relatedAuditItems": [
        "post-for-create-update",
        "http-methods-match-resources"
      ]
    },
    {
      "id": "REST-HTTP-PUT-01",
      "priority": "MUST",
      "category": "http-semantics",
      "requirement": "The REST API MUST use PUT only for full resource replacement.",
      "relatedAuditItems": [
        "post-for-create-update",
        "http-methods-match-resources"
      ]
    },
    {
      "id": "REST-HTTP-DELETE-01",
      "priority": "MUST",
      "category": "http-semantics",
      "requirement": "The REST API MUST use DELETE to remove resources.",
      "relatedAuditItems": [
        "delete-for-remove",
        "http-methods-match-resources"
      ]
    },
    {
      "id": "REST-PATH-01",
      "priority": "SHOULD",
      "category": "resource-modeling",
      "requirement": "The REST API SHOULD keep endpoint paths shallow and avoid more than two resource or sub-resource levels unless explicitly justified.",
      "relatedAuditItems": [
        "paths-max-two-resources"
      ]
    },
    {
      "id": "REST-RESP-200-01",
      "priority": "MUST",
      "category": "status-codes",
      "requirement": "The REST API MUST return 200 OK for successful reads and updates that include a response body.",
      "relatedAuditItems": [
        "get-no-request-body",
        "post-returns-200"
      ]
    },
    {
      "id": "REST-RESP-201-01",
      "priority": "MUST",
      "category": "status-codes",
      "requirement": "The REST API MUST return 201 Created and the created resource identifier when a new resource is created.",
      "relatedAuditItems": [
        "create-returns-identifiers",
        "post-returns-201"
      ]
    },
    {
      "id": "REST-RESP-204-01",
      "priority": "MUST",
      "category": "status-codes",
      "requirement": "The REST API MUST return 204 No Content for successful delete operations that do not return a body.",
      "relatedAuditItems": [
        "delete-returns-204"
      ]
    },
    {
      "id": "REST-RESP-204-02",
      "priority": "SHOULD",
      "category": "status-codes",
      "requirement": "The REST API SHOULD return 204 No Content for successful operations that intentionally return no response body.",
      "relatedAuditItems": [
        "get-empty-returns-204"
      ]
    },
    {
      "id": "REST-ERROR-400-01",
      "priority": "MUST",
      "category": "error-handling",
      "requirement": "The REST API MUST define 400 Bad Request responses with specific and actionable validation error information.",
      "relatedAuditItems": [
        "400-errors-specific"
      ]
    },
    {
      "id": "REST-ERROR-401-01",
      "priority": "MUST",
      "category": "error-handling",
      "requirement": "The REST API MUST return 401 Unauthorized for missing or invalid credentials.",
      "relatedAuditItems": [
        "401-unauthorized"
      ]
    },
    {
      "id": "REST-ERROR-403-01",
      "priority": "MUST",
      "category": "error-handling",
      "requirement": "The REST API MUST return 403 Forbidden for authenticated clients lacking sufficient permission.",
      "relatedAuditItems": [
        "403-forbidden"
      ]
    },
    {
      "id": "REST-VERSION-01",
      "priority": "MUST",
      "category": "versioning",
      "requirement": "The REST API MUST define a versioning strategy before production release, and the strategy MUST be supportable by the API gateway.",
      "relatedAuditItems": [
        "versioning-decided"
      ]
    },
    {
      "id": "REST-SEC-01",
      "priority": "MUST",
      "category": "security",
      "requirement": "The REST API MUST require authentication for protected endpoints.",
      "relatedAuditItems": [
        "auth-protection",
        "401-unauthorized"
      ]
    },
    {
      "id": "REST-SEC-02",
      "priority": "MUST",
      "category": "security",
      "requirement": "The REST API MUST use token-based authentication or another approved modern authentication mechanism for protected endpoints.",
      "relatedAuditItems": [
        "token-auth"
      ]
    },
    {
      "id": "REST-SEC-03",
      "priority": "MUST",
      "category": "security",
      "requirement": "The REST API MUST enforce object-level and function-level authorization on every protected operation.",
      "relatedAuditItems": [
        "401-unauthorized",
        "403-forbidden"
      ]
    },
    {
      "id": "REST-SEC-04",
      "priority": "MUST",
      "category": "security",
      "requirement": "The REST API MUST mitigate OWASP API risks including broken object level authorization, broken function level authorization, injection, and unrestricted resource consumption.",
      "relatedAuditItems": [
        "auth-protection",
        "rate-limits-enforced",
        "no-sensitive-data-in-urls",
        "message-integrity"
      ]
    },
    {
      "id": "REST-SEC-05",
      "priority": "MUST",
      "category": "security",
      "requirement": "The REST API MUST use HTTPS or another approved encrypted protocol for all traffic.",
      "relatedAuditItems": [
        "uses-https",
        "encryption-in-transit"
      ]
    },
    {
      "id": "REST-SEC-06",
      "priority": "MUST",
      "category": "security",
      "requirement": "The REST API MUST NOT expose sensitive information in URLs, query strings, logs, or unnecessary response fields.",
      "relatedAuditItems": [
        "no-sensitive-data-in-urls"
      ]
    },
    {
      "id": "REST-SEC-07",
      "priority": "SHOULD",
      "category": "security",
      "requirement": "The REST API SHOULD use UUIDs or other non-sequential public identifiers where direct database identifiers would increase exposure risk.",
      "relatedAuditItems": [
        "pseudo-identifiers"
      ]
    },
    {
      "id": "REST-SEC-08",
      "priority": "MUST",
      "category": "security",
      "requirement": "The REST API MUST implement CSRF protection where relevant to the authentication model and client interaction pattern.",
      "relatedAuditItems": [
        "csrf-protection"
      ]
    },
    {
      "id": "REST-CAPACITY-01",
      "priority": "MUST",
      "category": "resilience-capacity",
      "requirement": "The REST API MUST define and enforce rate limits, throttling, or quotas according to capacity expectations.",
      "relatedAuditItems": [
        "rate-limits-enforced"
      ]
    },
    {
      "id": "REST-CAPACITY-02",
      "priority": "MUST",
      "category": "resilience-capacity",
      "requirement": "The REST API MUST implement resilience controls such as timeouts, fallback behavior, and degradation handling according to business impact.",
      "relatedAuditItems": [
        "only-via-gateway"
      ]
    },
    {
      "id": "REST-OBS-01",
      "priority": "MUST",
      "category": "observability",
      "requirement": "The REST API MUST implement logs, metrics, and monitoring needed to observe validation failures, auth failures, traffic, latency, and dependency health.",
      "relatedAuditItems": [
        "rate-limits-enforced",
        "message-integrity"
      ]
    },
    {
      "id": "REST-PUBLISH-01",
      "priority": "MUST",
      "category": "publishing-governance",
      "requirement": "The REST API MUST be published through an API management platform.",
      "relatedAuditItems": [
        "published-via-api-management"
      ]
    },
    {
      "id": "REST-PUBLISH-02",
      "priority": "MUST",
      "category": "publishing-governance",
      "requirement": "The REST API MUST be accessible only through approved API gateway paths and managed entry points.",
      "relatedAuditItems": [
        "only-via-gateway"
      ]
    },
    {
      "id": "REST-PUBLISH-03",
      "priority": "SHOULD",
      "category": "publishing-governance",
      "requirement": "The REST API SHOULD be visible in a developer portal with documentation generated from the contract.",
      "relatedAuditItems": [
        "visible-in-dev-portal",
        "docs-auto-generated"
      ]
    },
    {
      "id": "REST-PUBLISH-04",
      "priority": "MUST",
      "category": "publishing-governance",
      "requirement": "The REST API MUST be published under an approved organizational domain.",
      "relatedAuditItems": [
        "official-domain"
      ]
    },
    {
      "id": "REST-AUDIT-01",
      "priority": "MUST",
      "category": "contract-governance",
      "requirement": "The REST API MUST validate the specification, schema, and examples on every change.",
      "relatedAuditItems": [
        "spec-validated-on-change",
        "schema-and-examples-pass"
      ]
    },
    {
      "id": "REST-AUDIT-02",
      "priority": "MUST",
      "category": "contract-governance",
      "requirement": "The REST API MUST pass concept, design, security, and production-readiness checks before release.",
      "relatedAuditItems": [
        "concept-items-audited",
        "design-items-audited"
      ]
    }
  ]
}

```

## Related stations

- [Suunnittelustandardit - Varmistaa johdonmukainen ja laadukas API-suunnittelu.](https://apiopscycles.com/fi/stations/design-standards.md)
- [Sopimussuunnittelu - Määrittele selkeät API-sopimukset](https://apiopscycles.com/fi/stations/contract-design.md)
