Skip to content

Scoring

The design guidelines explain what each dimension is for. This page is the mechanical half: how a score is computed, and every rule that actually runs.

Each dimension scores 100 × (1 − damage / capacity) — the share of that dimension’s rules the contract satisfies, weighted by how serious each one is. Two properties of that formula are deliberate:

  • A broken rule counts once, however often it fires. Otherwise a single chatty rule decides the dimension: oas3-parameter-description alone fires hundreds of times on a large document.
  • The denominator is the ruleset, not a fixed 100. Subtracting from a constant punishes documents for being detailed — a rule like owasp:api4:2023-string-limit can only fire on a contract that actually declares strings, so a document defining nothing would outscore a thorough one. Measured as a proportion of the rules in play, describing more of your API can no longer make your score worse by itself.

A dimension with no enabled rules behind it is not reported at all, rather than reported as a flawless 100. “Nothing was wrong” and “nothing was checked” must not look alike.

What a broken rule costs

A rule counts once however often it fires, priced by the severity its ruleset gives it:

SeverityCost
ERROR10
WARNING4
INFO1
HINT0.5

How dimensions are weighted

DimensionWeightWhat it measures
FC0.4Base layer of spec validity and structural soundness.
SEC0.3Trust, risk posture, and security compliance.
DX0.2Clarity, completeness, and ingestion readiness for developers and tooling.
MR0.1Assesses the API's readiness for mock testing and development.

Grade bands

  • A+≥ 98
  • A≥ 94
  • A-≥ 90
  • B+≥ 85
  • B≥ 80
  • B-≥ 75
  • C+≥ 67
  • C≥ 59
  • C-≥ 50
  • D+≥ 34
  • D≥ 17
  • D-≥ 0

Retuning scoring is two different kinds of change, on purpose:

Concern Where it lives Kind of change
Which rules run, their severity, their dimension api-scorer/rulesets/evaluation.yaml configuration — mountable from a ConfigMap, no rebuild
What a breach costs, dimension weights, grade bands api-scorer/src/domain/scoring.ts code

So a deployment can be retuned without a release, while the shape of the grading curve stays reviewable in one place.

Everything below is exported from the scorer itself rather than transcribed. The effective ruleset only exists after composition — Spectral’s oas rules plus the OWASP ruleset are merged, then the evaluation overlay overrides severities and stamps each rule with its dimension — so this list is generated by running that same composition:

Terminal window
cd api-scorer && npm run export:rules

That rewrites api-portal/src/data/scorer-rules.json, which these tables read. Re-run it whenever the ruleset or a Spectral dependency changes; the export carries no timestamp, so an unchanged ruleset produces an empty diff.

88 rules run against a OPENAPI contract, of which 11 are disabled by default and therefore counts towards neither findings nor coverage.

FC 21 rules

Base layer of spec validity and structural soundness.

RuleSeverityWhat it checks
array-itemsERROR
duplicated-entry-in-enumWARNINGEnum values must not have duplicate entry.
no-$ref-siblingsERRORProperty must not be placed among $ref
oas2-anyOfWARNINGanyOf is not available in OpenAPI v2, it was added in OpenAPI v3
oas2-discriminatorERRORdiscriminator property must be defined and required
oas2-oneOfWARNINGoneOf is not available in OpenAPI v2, it was added in OpenAPI v3
oas2-schemaERRORValidate structure of OpenAPI v2 specification.
oas2-unused-definitionWARNINGPotentially unused definition has been detected.
oas3_1-callbacks-in-webhookWARNING
oas3_1-servers-in-webhookWARNING
oas3-callbacks-in-callbacksWARNING
oas3-schemaERRORValidate structure of OpenAPI v3 specification.
oas3-unused-componentWARNING
operation-operationId-uniqueERROREvery operation must have unique "operationId".
operation-parametersWARNINGOperation parameters are unique and non-repeating.
operation-tag-definedWARNINGOperation tags must be defined in global tags.
path-declarations-must-existWARNING
path-keys-no-trailing-slashWARNING
path-not-include-queryWARNINGPath must not include query string.
path-paramsERRORPath parameters must be defined and valid.
typed-enumWARNINGEnum values must respect the specified type.

SEC 36 rules

Trust, risk posture, and security compliance.

RuleSeverityWhat it checks
no-eval-in-markdownWARNINGMarkdown descriptions must not have "eval(".
no-script-tags-in-markdownWARNINGMarkdown descriptions must not have "<script>" tags.
oas2-operation-security-definedWARNINGOperation "security" values must match a scheme defined in the "securityDefinitions" object.
oas3-operation-security-definedWARNINGOperation "security" values must match a scheme defined in the "components.securitySchemes" object.
owasp:api1:2023-no-numeric-idsERRORUse random IDs that cannot be guessed. UUIDs are preferred but any other random string will do.
owasp:api2:2023-auth-insecure-schemesERRORThere are many [HTTP authorization schemes](https://www.iana.org/assignments/http-authschemes/) but some of them are now considered insecure, such as negotiating authentication using specifications like NTLM or OAuth v1.
owasp:api2:2023-jwt-best-practicesERRORJSON Web Tokens RFC7519 is a compact, URL-safe, means of representing claims to be transferred between two parties. JWT can be enclosed in encrypted or signed tokens like JWS and JWE. The [JOSE IANA registry](https://www.iana.org/assignments/jose/jose.xhtml) provides algorithms information. RFC8725 describes common pitfalls in the JWx specifications and in their implementations, such as: - the ability to ignore algorithms, eg. `{"alg": "none"}`; - using insecure algorithms like `RSASSA-PKCS1-v1_5` eg. `{"alg": "RS256"}`. An API using JWT should explicit in the `description` that the implementation conforms to RFC8725. ``` components: securitySchemes: JWTBearer: type: http scheme: bearer bearerFormat: JWT description: |- A bearer token in the format of a JWS and conformato to the specifications included in RFC8725. ```
owasp:api2:2023-no-api-keys-in-urlERRORAPI Keys are are passed in headers, cookies or query parameters to access APIs Those keys can be eavesdropped, especially when they are passed in the URL as logging or history tools will keep track of them and potentially expose them.
owasp:api2:2023-no-credentials-in-urlERRORURL parameters MUST NOT contain credentials such as API key, password, or secret. See [RAC_GEN_004](https://docs.italia.it/italia/piano-triennale-ict/lg-modellointeroperabilita-docs/it/bozza/doc/04_Raccomandazioni%20di%20implementazione/04_raccomandazioni-tecniche-generali/01_globali.html?highlight=credenziali#rac-gen-004-non-passare-credenziali-o-dati-riservati-nellurl)
owasp:api2:2023-no-http-basicERRORBasic authentication credentials transported over network are more susceptible to interception than other forms of authentication, and as they are not encrypted it means passwords and tokens are more easily leaked.
owasp:api2:2023-read-restrictedWARNINGRead operations (GET, HEAD) should be secured by at least one security scheme. Security schemes are defined in the `securityScheme` section then referenced in the `security` key at the global or operation levels.
owasp:api2:2023-short-lived-access-tokensERRORUsing short-lived access tokens is a good practice, and when using OAuth 2 this is done by using refresh tokens. If a malicious actor is able to get hold of an access token then rotation means that token might not work by the time they try to use it, or it could at least reduce how long they are able to perform malicious requests.
owasp:api2:2023-write-restrictedERRORAll write operations (POST, PUT, PATCH, DELETE) must be secured by at least one security scheme. Security schemes are defined in the `securityScheme` section then referenced in the `security` key at the global or operation levels.
owasp:api3:2023-constrained-additionalPropertiesWARNINGBy default JSON Schema allows additional properties, which can potentially lead to mass assignment issues, where unspecified fields are passed to the API without validation. Disable them with `additionalProperties: false` or add `maxProperties`
owasp:api3:2023-constrained-unevaluatedPropertiesWARNINGBy default JSON Schema allows unevaluated properties, which can potentially lead to mass assignment issues, where unspecified fields are passed to the API without validation. Disable them with `unevaluatedProperties: false` or add `maxProperties`
owasp:api3:2023-no-additionalPropertiesWARNINGBy default JSON Schema allows additional properties, which can potentially lead to mass assignment issues, where unspecified fields are passed to the API without validation. Disable them with `additionalProperties: false` or add `maxProperties`.
owasp:api3:2023-no-unevaluatedPropertiesWARNINGBy default JSON Schema allows unevaluated properties, which can potentially lead to mass assignment issues, where unspecified fields are passed to the API without validation. Disable them with `unevaluatedProperties: false` or add `maxProperties`.
owasp:api4:2023-array-limitERRORArray size should be limited to mitigate resource exhaustion attacks. This can be done using `maxItems`. You should ensure that the subschema in `items` is constrained too.
owasp:api4:2023-integer-formatERRORIntegers should be limited to mitigate resource exhaustion attacks. Specifying whether int32 or int64 is expected via `format`.
owasp:api4:2023-integer-limitERRORIntegers should be limited to mitigate resource exhaustion attacks. This can be done using `minimum` and `maximum`, which can with e.g.: avoiding negative numbers when positive are expected, or reducing unreasonable iterations like doing something 1000 times when 10 is expected.
owasp:api4:2023-integer-limit-legacyERRORIntegers should be limited to mitigate resource exhaustion attacks. This can be done using `minimum` and `maximum`, which can with e.g.: avoiding negative numbers when positive are expected, or reducing unreasonable iterations like doing something 1000 times when 10 is expected.
owasp:api4:2023-rate-limitERRORDefine proper rate limiting to avoid attackers overloading the API. There are many ways to implement rate-limiting, but most of them involve using HTTP headers, and there are two popular ways to do that: IETF Draft HTTP RateLimit Headers:. https://datatracker.ietf.org/doc/draft-ietf-httpapi-ratelimit-headers/ Customer headers like X-Rate-Limit-Limit (Twitter: https://developer.twitter.com/en/docs/twitter-api/rate-limits) or X-RateLimit-Limit (GitHub: https://docs.github.com/en/rest/overview/resources-in-the-rest-api)
owasp:api4:2023-rate-limit-responses-429WARNINGOWASP API Security recommends defining schemas for all responses, even errors. A HTTP 429 response signals the API client is making too many requests, and will supply information about when to retry so that the client can back off calmly without everything breaking. Defining this response is important not just for documentation, but to empower contract testing to make sure the proper JSON structure is being returned instead of leaking implementation details in backtraces. It also ensures your API/framework/gateway actually has rate limiting set up.
owasp:api4:2023-rate-limit-retry-afterERRORDefine proper rate limiting to avoid attackers overloading the API. Part of that involves setting a Retry-After header so well meaning consumers are not polling and potentially exacerbating problems.
owasp:api4:2023-string-limitERRORString size should be limited to mitigate resource exhaustion attacks. This can be done using `maxLength`, `enum` or `const`.
owasp:api4:2023-string-restrictedWARNINGTo avoid unexpected values being sent or leaked, strings should have a `format`, RegEx `pattern`, `enum`, or `const`.
owasp:api5:2023-admin-security-uniqueERROR
owasp:api7:2023-concerning-url-parameterINFOUsing external resource based on user input for webhooks, file fetching from URLs, custom SSO, URL previews, or redirects, can lead to a wide variety of security issues. Learn more about Server Side Request Forgery here: https://owasp.org/API-Security/editions/2023/en/0xa7-server-side-request-forgery/
owasp:api8:2023-define-cors-originERRORSetting up CORS headers will control which websites can make browser-based HTTP requests to your API, using either the wildcard "*" to allow any origin, or "null" to disable any origin. Alternatively you can use "Access-Control-Allow-Origin: https://example.com" to indicate that only requests originating from the specified domain (https://example.com) are allowed to access its resources. More about CORS here: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS.
owasp:api8:2023-define-error-responses-401WARNINGOWASP API Security recommends defining schemas for all responses, even errors. The 401 describes what happens when a request is unauthorized, so its important to define this not just for documentation, but to empower contract testing to make sure the proper JSON structure is being returned instead of leaking implementation details in backtraces.
owasp:api8:2023-define-error-responses-500WARNINGOWASP API Security recommends defining schemas for all responses, even errors. The 500 describes what happens when a request fails with an internal server error, so its important to define this not just for documentation, but to empower contract testing to make sure the proper JSON structure is being returned instead of leaking implementation details in backtraces.
owasp:api8:2023-define-error-validationWARNINGCarefully define schemas for all the API responses, including either 400, 422 or 4XX responses which describe errors caused by invalid requests.
owasp:api8:2023-no-scheme-httpERRORServer interactions must use the http protocol as it's inherently insecure and can lead to PII and other sensitive information being leaked through traffic sniffing or man-in-the-middle attacks. Use the https or wss schemes instead. Learn more about the importance of TLS (over SSL) here: https://cheatsheetseries.owasp.org/cheatsheets/Transport_Layer_Protection_Cheat_Sheet.html
owasp:api8:2023-no-server-httpERRORServer interactions must not use the http:// as it's inherently insecure and can lead to PII and other sensitive information being leaked through traffic sniffing or man-in-the-middle attacks. Use https:// or wss:// protocols instead. Learn more about the importance of TLS (over SSL) here: https://cheatsheetseries.owasp.org/cheatsheets/Transport_Layer_Protection_Cheat_Sheet.html
owasp:api9:2023-inventory-accessERRORServers are required to use vendor extension x-internal set to true or false to explicitly explain the audience for the API, which will be picked up by most documentation tools.
owasp:api9:2023-inventory-environmentERRORMake it clear which servers are expected to run as which environment to avoid unexpected problems, exposing test data to the public, or letting bad actors bypass security measures to get to production-like environments.

DX 18 rules

Clarity, completeness, and ingestion readiness for developers and tooling.

RuleSeverityWhat it checks
contact-propertiesoffWARNINGContact object must have "name", "url" and "email".
info-contactERRORInfo object must have "contact" object.
info-descriptionERRORInfo "description" must be present and non-empty string.
info-licenseoffWARNINGInfo object must have "license" object.
license-urloffWARNINGLicense object must include "url".
oas2-operation-formData-consume-checkWARNINGOperations with "in: formData" parameter must include "application/x-www-form-urlencoded" or "multipart/form-data" in their "consumes" property.
oas2-parameter-descriptionoffWARNINGParameter objects must have "description".
oas3-parameter-descriptionoffWARNINGParameter objects must have "description".
openapi-tagsoffWARNINGOpenAPI object must have non-empty "tags" array.
openapi-tags-alphabeticaloffWARNINGOpenAPI object must have alphabetical "tags".
openapi-tags-uniquenessERROREach tag must have a unique name.
operation-descriptionWARNINGOperation "description" must be present and non-empty string.
operation-operationIdWARNINGOperation must have "operationId".
operation-operationId-valid-in-urlWARNING
operation-singular-tagoffWARNINGOperation must not have more than a single tag.
operation-success-responseWARNINGOperation must have at least one "2xx" or "3xx" response.
operation-tagsWARNINGOperation must have non-empty "tags" array.
tag-descriptionoffWARNINGTag object must have "description".

MR 13 rules

Assesses the API's readiness for mock testing and development.

RuleSeverityWhat it checks
oas2-api-hostWARNINGOpenAPI "host" must be present and non-empty string.
oas2-api-schemesWARNINGOpenAPI host "schemes" must be present and non-empty array.
oas2-host-not-exampleoffWARNINGHost URL must not point at example.com.
oas2-host-trailing-slashWARNINGServer URL must not have trailing slash.
oas2-valid-media-exampleERRORExamples must be valid against their defined schema.
oas2-valid-schema-exampleERRORExamples must be valid against their defined schema.
oas3-api-serversWARNINGOpenAPI "servers" must be present and non-empty array.
oas3-examples-value-or-externalValueWARNINGExamples must have either "value" or "externalValue" field.
oas3-server-not-example.comoffWARNINGServer URL must not point at example.com.
oas3-server-trailing-slashWARNINGServer URL must not have trailing slash.
oas3-server-variablesERRORServer variables must be defined and valid and there must be no unused variables.
oas3-valid-media-exampleERRORExamples must be valid against their defined schema.
oas3-valid-schema-exampleERRORExamples must be valid against their defined schema.

55 rules run against a ASYNCAPI contract, of which 8 are disabled by default and therefore counts towards neither findings nor coverage.

FC 54 rules

Base layer of spec validity and structural soundness.

RuleSeverityWhat it checks
asyncapi-3-channel-no-empty-parameterWARNINGChannel address must not have empty parameter substitution pattern.
asyncapi-3-channel-no-query-nor-fragmentWARNINGChannel address must not include query ("?") or fragment ("#") delimiter.
asyncapi-3-channel-no-trailing-slashWARNINGChannel address must not end with slash.
asyncapi-3-channel-serversERRORChannel servers must be defined in the "servers" object.
asyncapi-3-document-resolvedERRORChecking if the AsyncAPI v3 document has valid structure after resolving references.
asyncapi-3-document-unresolvedERRORChecking if the AsyncAPI v3 document has valid structure before resolving references.
asyncapi-3-headers-schema-type-objectERRORHeaders schema type must be "object".
asyncapi-3-operation-descriptionWARNINGOperation "description" must be present and non-empty string.
asyncapi-3-operation-securityERROROperation have to reference a defined security schemes.
asyncapi-3-payload-unsupported-schemaFormatINFOMessage schema validation is only supported with default unspecified "schemaFormat".
asyncapi-3-server-no-empty-variableWARNINGServer host and pathname must not have empty variable substitution pattern.
asyncapi-3-server-no-trailing-slashWARNINGServer host must not end with slash.
asyncapi-3-server-not-example-comoffWARNINGServer host must not point at example.com.
asyncapi-3-tag-descriptionoffWARNINGTag object must have "description".
asyncapi-3-tagsWARNINGAsyncAPI document must have non-empty "tags" array.
asyncapi-3-tags-alphabeticaloffWARNINGAsyncAPI object must have alphabetical "tags".
asyncapi-3-tags-uniquenessERROREach tag must have a unique name.
asyncapi-channel-no-empty-parameterWARNINGChannel path must not have empty parameter substitution pattern.
asyncapi-channel-no-query-nor-fragmentWARNINGChannel path must not include query ("?") or fragment ("#") delimiter.
asyncapi-channel-no-trailing-slashWARNINGChannel path must not end with slash.
asyncapi-channel-parametersERRORChannel parameters must be defined and there must be no redundant parameters.
asyncapi-channel-serversERRORChannel servers must be defined in the "servers" object.
asyncapi-headers-schema-type-objectERRORHeaders schema type must be "object".
asyncapi-info-contactWARNINGInfo object must have "contact" object.
asyncapi-info-contact-propertiesWARNINGContact object must have "name", "url" and "email".
asyncapi-info-descriptionWARNINGInfo "description" must be present and non-empty string.
asyncapi-info-licenseWARNINGInfo object must have "license" object.
asyncapi-info-license-urloffWARNINGLicense object must include "url".
asyncapi-latest-versionINFOChecking if the AsyncAPI document is using the latest version.
asyncapi-message-examplesERRORExamples of message object should follow by "payload" and "headers" schemas.
asyncapi-message-messageId-uniquenessERROR"messageId" must be unique across all the messages.
asyncapi-operation-descriptionWARNINGOperation "description" must be present and non-empty string.
asyncapi-operation-operationIdERROROperation must have "operationId".
asyncapi-operation-operationId-uniquenessERROR"operationId" must be unique across all the operations.
asyncapi-operation-securityERROROperation have to reference a defined security schemes.
asyncapi-payloadERRORPayloads must be valid against AsyncAPI Schema object.
asyncapi-payload-defaultERRORDefault must be valid against its defined schema.
asyncapi-payload-examplesERRORExamples must be valid against their defined schema.
asyncapi-payload-unsupported-schemaFormatINFOMessage schema validation is only supported with default unspecified "schemaFormat".
asyncapi-schemaERRORValidate structure of AsyncAPI specification.
asyncapi-schema-defaultERRORDefault must be valid against its defined schema.
asyncapi-schema-examplesERRORExamples must be valid against their defined schema.
asyncapi-server-no-empty-variableWARNINGServer URL must not have empty variable substitution pattern.
asyncapi-server-no-trailing-slashWARNINGServer URL must not end with slash.
asyncapi-server-not-example-comoffWARNINGServer URL must not point at example.com.
asyncapi-server-securityERRORServer have to reference a defined security schemes.
asyncapi-server-variablesERRORServer variables must be defined and there must be no redundant variables.
asyncapi-serversWARNINGAsyncAPI object must have non-empty "servers" object.
asyncapi-tag-descriptionoffWARNINGTag object must have "description".
asyncapi-tagsWARNINGAsyncAPI object must have non-empty "tags" array.
asyncapi-tags-alphabeticaloffWARNINGAsyncAPI object must have alphabetical "tags".
asyncapi-tags-uniquenessERROREach tag must have a unique name.
asyncapi-unused-components-schemaWARNINGPotentially unused components schema has been detected.
asyncapi-unused-components-serverWARNINGPotentially unused components server has been detected.

DX 1 rules

Clarity, completeness, and ingestion readiness for developers and tooling.

RuleSeverityWhat it checks
asyncapi-parameter-descriptionoffWARNINGParameter objects must have "description".