Stack Exchange · API Governance Rules
Stack Exchange API Rules
Spectral linting rules defining API design standards and conventions for Stack Exchange.
44 Rules
error 16
warn 20
info 8
Rule Categories
examples
http
info
no
openapi
operation
parameter
paths
response
schema
security
servers
tag
tags
Rules
error
info-title-stack-exchange
info.title must start with "Stack Exchange".
$.info.title
error
info-description-required
info.description is required and must be at least 60 characters.
$.info
error
info-version-required
info.version must follow Stack Exchange API versioning (2.x).
$.info.version
warn
info-terms-of-service-required
Stack Exchange API specs must reference the API Terms of Use.
$.info
warn
info-contact-url-required
info.contact.url must point to api.stackexchange.com.
$.info.contact
error
openapi-version-3
Only OpenAPI 3.0.x is supported for Stack Exchange specs.
$.openapi
error
servers-defined
servers array must be present with at least one entry.
$
error
servers-must-be-stackexchange-https
Server URL must be https://api.stackexchange.com/{version}.
$.servers[*].url
warn
servers-have-descriptions
Each server entry should have a description.
$.servers[*]
warn
paths-lowercase-kebab
Path segments must be lowercase with kebab-case for multi-word resources.
$.paths
error
paths-no-trailing-slash
Paths must not end with a trailing slash.
$.paths
error
paths-no-query-strings
Paths must not contain query strings; use parameters instead.
$.paths
warn
paths-camelcase-path-params
Path parameter placeholders should use camelCase (e.g. {ids}, {accessTokens}).
$.paths
info
paths-known-collections-plural
Stack Exchange root collections (questions, answers, comments, users, tags, badges, sites, posts, revisions, suggested-edits, events, filters, notifications) are plural nouns.
$.paths
error
operation-summary-required
Every operation must have a summary.
$.paths[*][get,post,put,patch,delete]
warn
operation-summary-stack-exchange-prefix
Operation summaries must begin with the company name "Stack Exchange".
$.paths[*][get,post,put,patch,delete].summary
warn
operation-description-required
Every operation must have a description.
$.paths[*][get,post,put,patch,delete]
error
operation-id-required
Every operation must have an operationId.
$.paths[*][get,post,put,patch,delete]
warn
operation-id-camelcase
operationId must be camelCase.
$.paths[*][get,post,put,patch,delete].operationId
warn
operation-id-verb-prefix
operationId should start with a known REST verb (list, get, search, find, create, update, delete, invalidate, read, deauthenticate).
$.paths[*][get,post,put,patch,delete].operationId
error
operation-tags-required
Every operation must be tagged with at least one tag.
$.paths[*][get,post,put,patch,delete]
info
operation-microcks-extension
Each operation should declare an x-microcks-operation block.
$.paths[*][get,post,put,patch,delete]
warn
tags-global-defined
Global tags array must be present with entries.
$
warn
tag-name-title-case
Tag names use Title Case (e.g. "Suggested Edits", "Access Tokens").
$.tags[*].name
info
tag-description-required
Each tag should have a description.
$.tags[*]
warn
parameter-description-required
Every reusable parameter must have a description.
$.components.parameters[*]
warn
parameter-snake-case-names
Query parameter names use snake_case (or single lowercase word).
$.paths[*][get,post,put,patch,delete].parameters[?(@.in=='query')].name
warn
parameter-pagination-canonical
Pagination uses `page` (1-indexed) and `pagesize` (max 100).
$.paths[*][get,post,put,patch,delete].parameters[?(@.name=='page' || @.name=='pagesize')]
warn
parameter-site-required-on-per-site-methods
Per-site methods must declare the `site` query parameter as required.
$.paths[*][get].parameters[?(@.name=='site' || @.$ref=='#/components/parameters/Site')]
info
parameter-api-key-in-query
API key is exchanged via the `key` query parameter (per Stack Exchange convention).
$.components.securitySchemes.apiKey
error
response-success-required
Every operation must declare a 2xx response.
$.paths[*][get,post,put,patch,delete].responses
warn
response-json-content
Success responses must include application/json content.
$.paths[*][get,post,put,patch,delete].responses['200','201','202','204']
info
response-schema-references-wrapper
Every success response schema should be (or extend) the Wrapper envelope.
$.paths[*][get,post,put,patch,delete].responses['200'].content.application/json.schema.$ref
error
response-description-required
Every response must have a description.
$.paths[*][get,post,put,patch,delete].responses[*]
warn
schema-property-snake-case
Schema properties use snake_case (Stack Exchange wire convention).
$.components.schemas[*].properties.*~
error
schema-wrapper-fields-present
The Wrapper schema must define has_more, quota_max, and quota_remaining.
$.components.schemas.Wrapper.properties
info
schema-timestamps-int64
Stack Exchange timestamps are Unix epoch seconds stored as int64.
$.components.schemas[*].properties[creation_date,last_activity_date,last_modified_date,last_access_date,last_edit_date,closed_date,protected_date,locked_date,community_owned_date,launch_date,expires_on_date,on_date]
warn
schema-types-defined
Every component schema must declare a type (object/array/string/...).
$.components.schemas[*]
error
security-schemes-defined
securitySchemes must declare oauth2 (write/private) and apiKey (quota).
$.components.securitySchemes
error
security-oauth2-stackexchange-endpoints
OAuth2 endpoints must point to stackoverflow.com.
$.components.securitySchemes.oauth2.flows.authorizationCode
warn
security-oauth2-known-scopes
Only Stack Exchange OAuth scopes are allowed (read_inbox, no_expiry, write_access, private_info).
$.components.securitySchemes.oauth2.flows.authorizationCode.scopes
info
http-methods-read-mostly
Stack Exchange v2.3 is read-mostly — GET is the dominant verb.
$.paths[*]
warn
no-empty-descriptions
Descriptions must not be empty strings.
$..description
info
examples-encouraged
Schema properties should have example values for documentation and mocking.
$.components.schemas[*].properties[?(@.type=='string' || @.type=='integer' || @.type=='boolean')]