Strapi · API Governance Rules

Strapi API Rules

Spectral linting rules defining API design standards and conventions for Strapi.

10 Rules error 1 warn 5 info 4
View Rules File View on GitHub

Rule Categories

strapi

Rules

warn
strapi-operation-ids-camel-case
Strapi operationIds use camelCase (e.g., findEntries, createEntry, listAdminUsers). All operation IDs must follow camelCase convention.
$.paths[*][*].operationId
warn
strapi-tags-title-case
All OpenAPI tags must use Title Case (e.g., 'Content Entries', 'Admin Users', 'API Tokens').
$.tags[*].name
warn
strapi-api-paths-prefix
All content API paths must begin with /api/. Admin API paths must begin with /admin/. Strapi enforces this routing convention.
$.paths
info
strapi-bearer-auth-on-protected-endpoints
Protected Strapi endpoints must declare security using bearerAuth or adminBearerAuth schemes. Public endpoints explicitly set security to [].
$.paths[*][get,put,delete,patch]
info
strapi-response-data-wrapper
Strapi REST API list responses wrap results in a 'data' array with a 'meta' object containing pagination. Single-entry responses wrap the entry in a 'data' object.
$.paths[*][get].responses['200'].content['application/json'].schema.properties
info
strapi-document-id-param-name
Strapi v5 uses 'documentId' as the path parameter for content entry identifiers. Path parameters for individual entries must be named 'documentId' (not 'id') in REST API paths.
$.paths['/api/{pluralApiId}/{documentId}'][*].parameters[*]
info
strapi-pagination-parameters
Strapi list endpoints support both page-based (pagination[page] / pagination[pageSize]) and offset-based (pagination[start] / pagination[limit]) pagination. Both styles use bracket notation.
$.paths[*][get].parameters[*].name
warn
strapi-error-schema-shape
Strapi error responses follow a consistent shape with a top-level 'data' (null) property and an 'error' object containing 'status', 'name', 'message', and 'details'.
$.components.schemas.Error.properties
error
strapi-operation-summaries-present
All operations must have a summary. Strapi docs use action-noun format (e.g., 'List content entries', 'Create a content entry').
$.paths[*][get,post,put,delete,patch]
warn
strapi-upload-multipart
Strapi file upload endpoints must use multipart/form-data content type.
$.paths['/api/upload'][post].requestBody.content

Spectral Ruleset

Raw ↑
extends:
  - spectral:oas

rules:
  strapi-operation-ids-camel-case:
    description: >-
      Strapi operationIds use camelCase (e.g., findEntries, createEntry,
      listAdminUsers). All operation IDs must follow camelCase convention.
    message: "OperationId '{{value}}' must use camelCase format"
    severity: warn
    given: "$.paths[*][*].operationId"
    then:
      function: pattern
      functionOptions:
        match: "^[a-z][a-zA-Z0-9]*$"

  strapi-tags-title-case:
    description: >-
      All OpenAPI tags must use Title Case (e.g., 'Content Entries',
      'Admin Users', 'API Tokens').
    message: "Tag '{{value}}' must use Title Case"
    severity: warn
    given: "$.tags[*].name"
    then:
      function: pattern
      functionOptions:
        match: "^[A-Z][a-zA-Z]*(\\s[A-Z][a-zA-Z]*)*$"

  strapi-api-paths-prefix:
    description: >-
      All content API paths must begin with /api/. Admin API paths must
      begin with /admin/. Strapi enforces this routing convention.
    message: "Path '{{property}}' must start with /api/ or /admin/"
    severity: warn
    given: "$.paths"
    then:
      field: "@key"
      function: pattern
      functionOptions:
        match: "^/(api|admin)/"

  strapi-bearer-auth-on-protected-endpoints:
    description: >-
      Protected Strapi endpoints must declare security using bearerAuth or
      adminBearerAuth schemes. Public endpoints explicitly set security to [].
    message: "Protected operation must declare bearerAuth or adminBearerAuth security"
    severity: info
    given: "$.paths[*][get,put,delete,patch]"
    then:
      function: truthy
      field: "security"

  strapi-response-data-wrapper:
    description: >-
      Strapi REST API list responses wrap results in a 'data' array with a
      'meta' object containing pagination. Single-entry responses wrap the
      entry in a 'data' object.
    message: "200 response should include a 'data' property at the top level"
    severity: info
    given: "$.paths[*][get].responses['200'].content['application/json'].schema.properties"
    then:
      function: truthy
      field: "data"

  strapi-document-id-param-name:
    description: >-
      Strapi v5 uses 'documentId' as the path parameter for content entry
      identifiers. Path parameters for individual entries must be named
      'documentId' (not 'id') in REST API paths.
    message: "Content entry path parameter should be named 'documentId'"
    severity: info
    given: "$.paths['/api/{pluralApiId}/{documentId}'][*].parameters[*]"
    then:
      field: "name"
      function: enumeration
      functionOptions:
        values:
          - documentId
          - pluralApiId

  strapi-pagination-parameters:
    description: >-
      Strapi list endpoints support both page-based (pagination[page] /
      pagination[pageSize]) and offset-based (pagination[start] /
      pagination[limit]) pagination. Both styles use bracket notation.
    message: "List endpoints should document pagination parameters using bracket notation"
    severity: info
    given: "$.paths[*][get].parameters[*].name"
    then:
      function: pattern
      functionOptions:
        notMatch: "^page$|^pageSize$|^limit$|^offset$"

  strapi-error-schema-shape:
    description: >-
      Strapi error responses follow a consistent shape with a top-level
      'data' (null) property and an 'error' object containing 'status',
      'name', 'message', and 'details'.
    message: "Error schema must include 'data' and 'error' properties"
    severity: warn
    given: "$.components.schemas.Error.properties"
    then:
      - function: truthy
        field: "data"
      - function: truthy
        field: "error"

  strapi-operation-summaries-present:
    description: >-
      All operations must have a summary. Strapi docs use action-noun
      format (e.g., 'List content entries', 'Create a content entry').
    message: "Operation must have a summary"
    severity: error
    given: "$.paths[*][get,post,put,delete,patch]"
    then:
      function: truthy
      field: "summary"

  strapi-upload-multipart:
    description: >-
      Strapi file upload endpoints must use multipart/form-data content type.
    message: "Upload endpoint must use multipart/form-data"
    severity: warn
    given: "$.paths['/api/upload'][post].requestBody.content"
    then:
      function: truthy
      field: "multipart/form-data"