In order to provide a consistent API as a platform, Snyk APIs have additional requirements, building on JSON API and Versioning standards.
Resources in the Snyk v3 API are located under an Organization and possibly a Group tenant, specified as a path prefix.
Resources addressed by Organization begin with /v3/orgs/{org_id}/...
.
Resources addressed by Group begin with /v3/groups/{group_id}/...
.
Additional resource properties that must be used in resource attributes, where applicable.
These properties are optional on a resource, but should be used when applicable. These properties must be formatted as ISO-8601 date-time strings.
When the resource was created (POST).
When the resource was last updated (PATCH).
When the resource was deleted (DELETE), if the DELETE operation marks the resource for deletion, or removes part of its content without actually removing the existence of the resource.
Casing conventions referenced below are defined in Spectral's casing function documentation.
API paths locate resources and collections of resources. These are always nouns. Collections should use the plural form of the noun. For example:
/things
(collection of things)/things/{thing_id}
(a specific thing, located in a collection of them)/orgs/{org_id}/other_things
(a collection located in a specific org, located in a collection of orgs)
When using camel or pascal case, acronyms are treated as any other concatenated word. For example, OrgId
, not OrgID
. This avoids ambiguity and information loss that would otherwise interfere with automated processing of the API schema. For example, a camel case name following these acronym rules can be translated into snake case to produce more conventional Python symbol names.
Resource collection names, parameters and path variables must use snake case names.
/some_resource/{resource_id}?foo_param=foo&bar_param=bar
Because these variables are represented in URLs, uppercase letters may cause problems on some client platforms; RFCs recommend that URLs are treated as case-sensitive, but it is a "should", not a "must". Dashes might cause problems for some code generators, ruling out kebab case.
Entities referenced in other documents (using $ref
) must use pascal case names.
Entities will be commonly represented as types or classes when generating code. Pascal case names are conventionally used for such symbols in most targeted languages.
Schema properties use snake case names.
When naming an operation, think carefully about how it will look and feel in generated code. Operations generally map to method or function names.
Operation IDs should be readable, intuitive and self-descriptive.
Operation IDs must use camel case names. Example:
operationId: getFoo
- GET becomes
get
for a single resource (by unique ID) - GET becomes
list
for multiple resources (pagination and filtering) - POST becomes
create
- PATCH becomes
update
- DELETE becomes
delete
Use the singular form if the operation operates on a single resource, plural if it operates on a collection operation.
Examples:
getFoo
(get one)listFoos
(get many)createThing
(create one)updateOtherThing
(update one)deleteThings
(bulk delete)
If there are multiple ways to address the resource by tenancy, differentiate these as a resource name suffix.
Example: getFooByOrg
, deleteProjectByGroup
, etc.
headers:
snyk-requested-version: 2021-08-21~beta
snyk-resolved-version: 2021-08-12~beta
Header field names are case insensitive. Snyk v3 API specs must use kebab case for consistency. All non-standard headers that are unique to Snyk must begin with snyk-
(e.g. snyk-requested-version
).
Certain headers are required in all v3 API responses.
snyk-request-id
- Relays a provided request UUID, or generates a new one, which is used to correlate the request to logs and downstream requests to other services.- Versioning response headers.
In addition to the status codes specified in JSON-API#Responses, we have standardized on additional situations across our surface area, specifically, for dealing with error cases.
All status codes must be listed in this section or as a part of the JSON-API Specification. As a general guiding principle, we strive to limit the number of status codes we return into large categorically distinct areas to make working with the Snyk API easier for end-users.
A bad request status code & error response must be returned when the user provided an syntactically invalid request header, query parameters, path parameters, or request body. For example, if an Authorization
header was malformed, then we'd return a 400 Bad Request
where as if we were provided an expired credential (e.g. JWT), we'd want to return a 401 Unauthorized
.
An unauthorized status code & error response must be returned when the requester provides an invalid (e.g. a bad signature) or expired credential. For example, if a requester were to provide a credential (e.g. a JSONWebToken) that was not signed by Snyk, we'd return a 401 Unauthorized
.
A forbidden status code & error response must be returned if the requester has provided a valid credential but the identity (e.g. user, service account, app) does not have the required permissions to perform the action. For example, if a user attempts to add a user to an organization but does not have the appropriate permissions to do so. A forbidden should only occur on write actions such as a create, update, or delete. If the requester does not have read access they should receive a 404 Not Found
.
A not found status code & error response must be returned if the requested resource does not exist or if the requester does not have access to the underlying resource. For example, if an org named pineapple
exists but the user joe
is not a member of the organization, then Joe should receive a 404 Not Found
when requesting any information related to the pineapple
organization.
A conflict status code & error response must be returned if a requested write action cannot be performed because it collides with some constraint (e.g. a unique constraint violation). This status code is also useful when processing idempotent requests which currently are not supported as a part of the Snyk API.
A too many requests status code & error response must be returned if the requester has exceeded their request quota for some given time period.
The quality of documentation generated from an OpenAPI specification depends quite a bit on content provided in certain fields. Redoc-generated documentation is used below to illustrate the purpose of these fields and why we require them.
The operations (GET, POST, etc) declared for resource paths must be organized with Tags. Tags are used to categorize the endpoints that operate on resources.
Tags organize the operations such as "List Issue Summaries" or "Get a Snyk Code Issue" under a single Resource category "Issues".
The operation summary
field provides a more useful and informative string that documents what the request method actually does. In the example above, one operation summary shown is "List Issue Summaries". If this is not specified, the operationId
(getIssuesSummary) would have been displayed instead.
format: uuid
and format: date-time
are essential for indicating a field is not just a string, but actually a UUID or an RFC3339 date string. This format is relied upon by request and response validation middleware.
Enum types ({type: string, enum: [...]}
) should be used wherever it is possible to enumerate a closed set of valid values a field might have. This includes the set of resource types in our API.
Enums make for great self-documenting APIs.
Request parameters and data attributes in response data schema objects need the example
field set in order to provide useful documentation. These are
With examples, it's clear what to expect. One could even run a mock API server with this content!
Without examples, as an end-user I don't have much context here to know what these fields' values are going to look like! Links are most likely URLs, not just strings!
Every service in the v3 API must publish endpoints that list available versions and fetch specific published versions of the OpenAPI spec for all resources provided by that service to v3. These paths may be prefixed if needed (some services may provide other APIs in addition to v3).
These endpoints need to be defined in the OpenAPI spec at all versions. They are not JSON API resources, and are not themselves versioned. Response type is application/json
.
Lists the available published versions of the API. Response body is an array of version strings.
Provides the OpenAPI 3 spec at {version}
in JSON format. The version is resolved by the same rules used to match the requested version.