Basecamp API Rules
Spectral linting rules defining API design standards and conventions for Basecamp.
22 Rules
error 10
warn 12
Rule Categories
error
get
info
no
oauth2
openapi
operation
parameter
path
query
response
schema
security
servers
Rules
error
info-title-required
Info must have a title
$.info
error
info-version-required
Info must have a version
$.info
error
openapi-version-3
Must use OpenAPI 3.x
$
error
servers-https-only
All server URLs must use HTTPS
$.servers[*].url
error
operation-summary-required
Every operation must have a summary
$.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-camel-case
OperationIds should use camelCase
$.paths[*][get,post,put,patch,delete].operationId
warn
operation-tags-required
Every operation must have tags
$.paths[*][get,post,put,patch,delete]
error
response-description-required
Every response must have a description
$.paths[*][get,post,put,patch,delete].responses[*]
warn
response-401-defined
Operations should define 401 response
$.paths[*][post,put,patch,delete]
error
security-schemes-defined
Security schemes must be defined
$.components
error
oauth2-required
Basecamp APIs must use OAuth2 authentication
$.components.securitySchemes[*]
warn
parameter-description-required
All parameters must have descriptions
$.paths[*][get,post,put,patch,delete].parameters[*]
warn
schema-type-defined
All schemas should have a type
$.components.schemas[*]
error
get-no-request-body
GET operations must not have a request body
$.paths[*].get
warn
path-params-casing
Path parameters should be camelCase (the dominant convention in this API).
$.paths[*].parameters[?(@.in=='path')].name
warn
query-params-casing
Query parameters should be snake_case (the dominant convention in this API).
$.paths[*][get,post,put,patch,delete].parameters[?(@.in=='query')]
warn
schema-names-casing
Component schema names should be PascalCase (the dominant convention in this API).
$.components.schemas
warn
schema-properties-casing
Schema properties should be snake_case (the dominant convention in this API).
$.components.schemas[*].properties
warn
error-schema-defined
A shared error schema (Error) should be defined for error payloads.
$.components.schemas
warn
operation-documents-401
Operations should document a 401 response (documented on 99% of this API's operations).
$.paths[*][get,post,put,patch,delete].responses
warn
no-empty-descriptions
Descriptions must not be empty strings.
$..description
Spectral Ruleset
# authorship: generated by API Evangelist tooling. Stamped 2026-08-18
# on the file's own generator header (roadmap#64). An unmarked file is
# NOT assumed to be ours -- absence of evidence was never stamped.
x-method: generated
# basecamp — Spectral ruleset (strengthened)
# Plain Spectral. Existing hand-authored rules preserved; measured rules added
# from this provider's own OpenAPI conventions by strengthen_ruleset.py,
# then self-validated against the spec.
#
# Provenance:
# - servers-https-only: 100% of servers already https (error)
# - path-params-casing: camel @ 100% (n=66)
# - query-params-casing: snake @ 100% (n=16)
# - operationid-casing: camel @ 100% (n=77)
# - schema-names-casing: pascal @ 100% (n=53)
# - schema-properties-casing: snake @ 100% (n=197)
# - security: global (root) — NOT emitting operation-security-required
# - error-schema-defined: Error
# - operation-documents-401: 99% adherence
# - merge: kept 15 existing, added 7 measured, upgraded 0
# - added: path-params-casing, query-params-casing, schema-names-casing, schema-properties-casing, error-schema-defined, operation-documents-401, no-empty-descriptions
extends:
- spectral:oas
rules:
info-title-required:
description: Info must have a title
severity: error
given: $.info
then:
field: title
function: truthy
info-version-required:
description: Info must have a version
severity: error
given: $.info
then:
field: version
function: truthy
openapi-version-3:
description: Must use OpenAPI 3.x
severity: error
given: $
then:
field: openapi
function: pattern
functionOptions:
match: ^3\.
servers-https-only:
description: All server URLs must use HTTPS
severity: error
given: $.servers[*].url
then:
function: pattern
functionOptions:
match: ^https://
operation-summary-required:
description: Every operation must have a summary
severity: error
given: $.paths[*][get,post,put,patch,delete]
then:
field: summary
function: truthy
operation-id-required:
description: Every operation must have an operationId
severity: error
given: $.paths[*][get,post,put,patch,delete]
then:
field: operationId
function: truthy
operation-id-camel-case:
description: OperationIds should use camelCase
severity: warn
given: $.paths[*][get,post,put,patch,delete].operationId
then:
function: pattern
functionOptions:
match: ^[a-z][a-zA-Z0-9]*$
operation-tags-required:
description: Every operation must have tags
severity: warn
given: $.paths[*][get,post,put,patch,delete]
then:
field: tags
function: truthy
response-description-required:
description: Every response must have a description
severity: error
given: $.paths[*][get,post,put,patch,delete].responses[*]
then:
field: description
function: truthy
response-401-defined:
description: Operations should define 401 response
severity: warn
given: $.paths[*][post,put,patch,delete]
then:
field: responses.401
function: truthy
security-schemes-defined:
description: Security schemes must be defined
severity: error
given: $.components
then:
field: securitySchemes
function: truthy
oauth2-required:
description: Basecamp APIs must use OAuth2 authentication
severity: error
given: $.components.securitySchemes[*]
then:
field: type
function: pattern
functionOptions:
match: ^oauth2$
parameter-description-required:
description: All parameters must have descriptions
severity: warn
given: $.paths[*][get,post,put,patch,delete].parameters[*]
then:
field: description
function: truthy
schema-type-defined:
description: All schemas should have a type
severity: warn
given: $.components.schemas[*]
then:
field: type
function: truthy
get-no-request-body:
description: GET operations must not have a request body
severity: error
given: $.paths[*].get
then:
field: requestBody
function: falsy
path-params-casing:
description: Path parameters should be camelCase (the dominant convention in this API).
severity: warn
given: $.paths[*].parameters[?(@.in=='path')].name
then:
function: casing
functionOptions:
type: camel
query-params-casing:
description: Query parameters should be snake_case (the dominant convention in this API).
severity: warn
given: $.paths[*][get,post,put,patch,delete].parameters[?(@.in=='query')]
then:
field: name
function: casing
functionOptions:
type: snake
schema-names-casing:
description: Component schema names should be PascalCase (the dominant convention in this API).
severity: warn
given: $.components.schemas
then:
field: '@key'
function: casing
functionOptions:
type: pascal
schema-properties-casing:
description: Schema properties should be snake_case (the dominant convention in this API).
severity: warn
given: $.components.schemas[*].properties
then:
field: '@key'
function: casing
functionOptions:
type: snake
error-schema-defined:
description: A shared error schema (Error) should be defined for error payloads.
severity: warn
given: $.components.schemas
then:
field: Error
function: truthy
operation-documents-401:
description: Operations should document a 401 response (documented on 99% of this API's operations).
severity: warn
given: $.paths[*][get,post,put,patch,delete].responses
then:
field: '401'
function: truthy
no-empty-descriptions:
description: Descriptions must not be empty strings.
severity: warn
given: $..description
then:
function: truthy