# Kraken Spectral Ruleset # Generated by the API Evangelist pipeline. Enforces Kraken's documented # conventions across the Spot REST and Futures REST OpenAPI specs. # # Dominant patterns observed: # - Operation summaries begin with "Kraken " # - operationId is camelCase # - Spot REST paths use PascalCase under /0/public/* and /0/private/* # - Futures REST paths use single-word lower-case under / # - All private endpoints use the kraken_signature / futures_signature API key # security scheme # - Every endpoint returns the standard {error, result} envelope # - HTTPS is required on every server URL except FIX colocation hosts # # Reference: https://docs.kraken.com/api/ extends: [["@stoplight/spectral:oas", off]] functionsDir: ./functions rules: # --------------------------------------------------------------------------- # INFO / METADATA # --------------------------------------------------------------------------- info-title-kraken-prefix: description: API title must start with "Kraken". severity: error given: $.info.title then: function: pattern functionOptions: { match: "^Kraken " } info-description-required: description: info.description must be present and at least 60 characters. severity: warn given: $.info then: - field: description function: truthy - field: description function: length functionOptions: { min: 60 } info-contact-required: description: info.contact with name and url is required. severity: warn given: $.info.contact then: - field: name function: truthy - field: url function: truthy info-license-required: description: info.license must reference Kraken Terms of Service. severity: warn given: $.info.license then: - field: name function: truthy - field: url function: pattern functionOptions: { match: "kraken.com" } info-version-required: description: info.version is required. severity: error given: $.info then: field: version function: truthy # --------------------------------------------------------------------------- # OPENAPI VERSION # --------------------------------------------------------------------------- openapi-3-0-required: description: Kraken specs must use OpenAPI 3.0.x. severity: error given: $.openapi then: function: pattern functionOptions: { match: "^3\\.0\\." } # --------------------------------------------------------------------------- # SERVERS # --------------------------------------------------------------------------- servers-required: description: At least one server URL must be defined. severity: error given: $.servers then: function: length functionOptions: { min: 1 } servers-https-only: description: REST server URLs must use https. severity: error given: $.servers[*].url then: function: pattern functionOptions: { match: "^https://" } servers-description-required: description: Every server must include a description. severity: warn given: $.servers[*] then: field: description function: truthy # --------------------------------------------------------------------------- # PATHS # --------------------------------------------------------------------------- paths-no-trailing-slash: description: Paths must not end with a trailing slash (other than root). severity: error given: $.paths.*~ then: function: pattern functionOptions: { notMatch: ".+/$" } paths-no-query-string: description: Paths must not embed query strings. severity: error given: $.paths.*~ then: function: pattern functionOptions: { notMatch: "\\?" } paths-spot-rest-prefix: description: Spot REST paths must start with /0/public/ or /0/private/. severity: warn given: $.paths.*~ then: function: pattern functionOptions: { match: "^(/0/(public|private)/|/[a-z][a-zA-Z]*)" } # --------------------------------------------------------------------------- # OPERATIONS # --------------------------------------------------------------------------- operation-operationId-required: description: Every operation must declare an operationId. severity: error given: $.paths.*[get,post,put,delete,patch] then: field: operationId function: truthy operation-operationId-camelcase: description: operationId must be camelCase. severity: error given: $.paths.*[get,post,put,delete,patch].operationId then: function: pattern functionOptions: { match: "^[a-z][a-zA-Z0-9]*$" } operation-summary-required: description: Every operation must have a summary. severity: error given: $.paths.*[get,post,put,delete,patch] then: field: summary function: truthy operation-summary-kraken-prefix: description: Operation summary must begin with "Kraken ". severity: warn given: $.paths.*[get,post,put,delete,patch].summary then: function: pattern functionOptions: { match: "^Kraken " } operation-description-required: description: Every operation must have a description. severity: warn given: $.paths.*[get,post,put,delete,patch] then: field: description function: truthy operation-tags-required: description: Every operation must be tagged. severity: error given: $.paths.*[get,post,put,delete,patch] then: field: tags function: truthy operation-microcks-extension: description: Operations should declare x-microcks-operation for mock-server compatibility. severity: info given: $.paths.*[get,post,put,delete,patch] then: field: x-microcks-operation function: truthy # --------------------------------------------------------------------------- # TAGS # --------------------------------------------------------------------------- tag-global-required: description: Global tags array must be defined with descriptions. severity: warn given: $.tags then: function: length functionOptions: { min: 1 } tag-description-required: description: Every tag must have a description. severity: warn given: $.tags[*] then: field: description function: truthy tag-title-case: description: Tag names must be Title Case (e.g. "Market Data", "Trading"). severity: warn given: $.tags[*].name then: function: pattern functionOptions: { match: "^[A-Z][A-Za-z0-9]*( [A-Z][A-Za-z0-9]*)*$" } # --------------------------------------------------------------------------- # PARAMETERS # --------------------------------------------------------------------------- parameter-description-required: description: Every parameter must have a description. severity: warn given: $.paths.*[get,post,put,delete,patch].parameters[*] then: field: description function: truthy parameter-schema-type-required: description: Every parameter must declare a schema.type. severity: error given: $.paths.*[get,post,put,delete,patch].parameters[*].schema then: field: type function: truthy # --------------------------------------------------------------------------- # REQUEST BODIES # --------------------------------------------------------------------------- request-body-form-or-json: description: Kraken Spot REST requests must use application/x-www-form-urlencoded or application/json. severity: warn given: $.paths.*[post,put,patch].requestBody.content then: function: enumeration functionOptions: values: - application/x-www-form-urlencoded - application/json request-nonce-required: description: Private request schemas should reference the nonced base (NoncedRequest) so a nonce field is always present. severity: info given: $.paths.*[post].requestBody.content['application/x-www-form-urlencoded'].schema then: function: truthy # --------------------------------------------------------------------------- # RESPONSES # --------------------------------------------------------------------------- response-2xx-required: description: Every operation must define at least one 2xx response. severity: error given: $.paths.*[get,post,put,delete,patch].responses then: function: pattern functionOptions: { match: "^2" } response-application-json: description: 200 responses must include an application/json media type. severity: warn given: $.paths.*[get,post,put,delete,patch].responses['200'].content then: field: application/json function: truthy response-envelope-shape: description: Spot REST 200 responses should resolve to the {error, result} envelope (BaseEnvelope allOf). severity: info given: $.paths.*[get,post].responses['200'].content['application/json'].schema then: function: truthy # --------------------------------------------------------------------------- # SCHEMAS # --------------------------------------------------------------------------- schema-property-snake-case: description: Schema property names must be snake_case (matches Kraken REST wire format). severity: warn given: $.components.schemas[*].properties then: function: pattern functionOptions: { match: "^[a-z][a-z0-9_]*$" } field: "@key" schema-type-required: description: Every schema must declare a type or use allOf/oneOf/$ref. severity: warn given: $.components.schemas[*] then: function: truthy # --------------------------------------------------------------------------- # SECURITY # --------------------------------------------------------------------------- security-schemes-defined: description: Specs must declare at least one security scheme. severity: error given: $.components.securitySchemes then: function: truthy security-scheme-kraken-signature: description: Spot REST must declare the kraken_signature API key security scheme. severity: warn given: $.components.securitySchemes then: function: truthy # --------------------------------------------------------------------------- # HTTP METHOD CONVENTIONS # --------------------------------------------------------------------------- get-no-request-body: description: GET operations must not declare a requestBody. severity: error given: $.paths.*[get] then: field: requestBody function: falsy delete-no-request-body: description: DELETE operations must not declare a requestBody. severity: warn given: $.paths.*[delete] then: field: requestBody function: falsy