Getting started

This page contains background on how to start using the Crunchy Bridge API, and information on core concepts common to all endpoints. See also the API reference which is an exhaustive specification of each endpoint, its request/response structures, and examples of use.

New additions to the API and changes made to it are listed in the changelog.

Authentication

Clients authenticate with the Crunchy Bridge API by way of an access token, which is a short-lived secret procured with a long-lived API key. In case an access token is accidentally leaked (for example, sent to a log which ends up in a long-term archive), this model makes a catastrophic security problem less likely because it won’t be long before it expires.

First, go to your account settings, scroll to the “API Keys” section, and click Create API Key, which generates an application ID and application secret for your use.

Once you have those, use them to make a request to POST /access-tokens:

curl -X POST https://api.crunchybridge.com/access-tokens \
    -H "Content-Type: application/json" \
    -d '{"client_id":"'$APPLICATION_ID'","client_secret":"'$APPLICATION_SECRET'","grant_type":"client_credentials"}'

The API will respond with a freshly created access token:

{
    "access_token": "cbat_joKobuWQH7i40L6y9LInnjVn4c_9X9Z_BOnHz4QiBrc",
    "account_id": "qvcw4hylovgyzbwzp53bmmlhga",
    "api_key_id": "ryexlkxpibfang6u7374faajfe",
    "expires_in": 3600,
    "id": "rizcplozgfht7lhra5lbqebiru",
    "token_type": "bearer"
}

The access_token field contains the secret which will be used to authenticate subsequent API requests, valid for one hour until a new one will need to be procured. The access token is supplied to API endpoints as a bearer token in the Authorization header. For example:

curl -H "Authorization: Bearer cbat_joKobuWQH7i40L6y9LInnjVn4c_9X9Z_BOnHz4QiBrc"

You export this to a variable for use with the cURL sample found on this site:

export CRUNCHY_ACCESS_TOKEN=cbat_joKobuWQH7i40L6y9LInnjVn4c_9X9Z_BOnHz4QiBrc

API compatibility

The Crunchy Bridge API aims to be as backwards compatible as possible, and will avoid changes which aren’t considered backwards compatible:

  • Removing an endpoint or changing its HTTP verb/URL.
  • Adding a new required request parameter to an endpoint, or making a request parameter that was previously optional required.
  • Removing a field on an endpoint response.
  • Changing the type of a field in an endpoint response.

We don’t commit to never making a backwards incompatible change, but will only so if it’s important, and carefully. Any such changes will be announced beforehand and codified in the changelog.

HTTP verbs

The API tries to make appropriate use of HTTP verbs depending on the type of operation:

  • GET: Used for read-only requests like listing and retrieval. Always idempotent.
  • POST: Used for non-idempotent mutation endpoints like where when an API resource is created. Can be made idempotent with idempotency keys.
  • PATCH: Used for endpoints where an API resource is being mutated non-idempotently. Can be made idempotent with idempotency keys.
  • PUT: Used for endpoints where an API resource is being mutated idempotently. Generally, PUT endpoints can be used as upsert-style “create or update” actions. Always idempotent.
  • DELETE: Used for endpoints where an API resource is being destroyed. Always idempotent.

💡Hint

Programs integrating with the Bridge API can be made much more robust against intermittent faults by considering idempotency while building them, and trying to use appropriate idempotent techniques. This is often as simple as generating a preflight value for the Idempotency-Key header, and retrying failed requests in case of error. See idempotency for full details on this subject.

Status codes

The API tries to make appropriate use of common HTTP status codes in responses. See the following matrix of status codes which are commonly returned and under what circumstances.

Code Status Description
200 OK Returned for most successful responses.
201 Created Returned in cases where a new resource has been created. For example, when creating a new cluster with POST /clusters.
204 No content Indicates an empty response body. In general this status code has largely been retired because it’s not optimal for compatibility, but you may still encounter it in some places.
400 Bad request Indicates that the incoming request is invalid – usually because it didn’t supply enough parameters or the parameters were incorrect. Make sure to examine the response error message for more specific details. See errors below.
401 Unauthorized No credentials were provided or the credentials were invalid. Usually means that an access token wasn’t sent or is expired.
403 Forbidden The client authenticated correctly, but isn’t allowed access to the target resource. This may mean that an account’s role doesn’t have sufficient permissions to perform the action.
404 Not found A requested resource wasn’t found, which may mean that one of the supplied IDs was bad. Make sure to examine the response error message for more specific details. See errors below.
405 Method not allowed Occurs when an endpoint is invoked for which the path is valid, but the HTTP method used (e.g. GET versus POST) was not.
409 Conflict Occurs when a request conflicts with another closely timed request and couldn’t be performed. See idempotency for more information.
410 Gone As a convenience to clients, the API may respond with a 410 instead of a 404 when it detects that a resource wasn’t found, but that it did exist previously and has subsequently been deleted. Don’t rely on certain IDs returning 410s forever as old resources are eventually fully recycled out of the system – this is meant as a short term tool to confirm that a DELETE operation succeeded in the case it had to be retried.
429 Too many requests Indicates that the request has been rate limited and that the client should slow down in making requests.
500 Internal server error An internal problem has occurred. We aim to make these as rare as possible and the error will be forwarded to an engineer to look at, but you may open a support ticket in case it’s urgent.

Precise status code compatibility isn’t guaranteed, so best practice is to write clients to be tolerant of a variety of possible status codes. For example, don’t write a client that requires a create action always return exactly a 201 – allow anything in the range of >= 200 and < 300 instead.

Some idempotent endpoints may use status code to hint at the action which occurred. For example when creating/updating a cluster logger, a 200 will indicate that an existing logger was updated while a 201 will indicate that one was freshly created.

Some endpoints may return a 410 instead of a 404 for a resource which wasn’t found when it recognizes that although an ID doesn’t exist anymore, it did exist previously. Clients trying to handle a case of a resource not found should respect either status code.

Errors

Error status codes give a broad hint as to the problem that may have occurred, but are often not specific enough to be helpful. The API will almost always provide a more detailed error message embedded in the response.

{
    "message":"Invalid credentials supplied for access to this resource.",
    "request_id":"5f805450-3565-4f34-8330-4ecb60d08bb9"
}

The error will also contain a request_id. In cases of an internal problem, it may be useful to provide this to support so that we can more easily locate the logs of the exact request which failed.

Pagination

List endpoints are paginated with cursor-based pagination. They’ll return 100 items by default so it may not be necessary to integrate with it right away, but you may need to eventually, especially for larger collections. Paginated endpoints have these page-related parameters:

  • cursor: A cursor the beginning of the page to retrieve, usually procured by reading the value of the next_cursor field in a previous page. Left empty to get the first page.
  • limit: The maximum number of items to return on the page. Defaults to 100 with a minimum of 1 and a maximum of 100.
  • order: The order of pagination. asc for ascending or desc for descending. Defaults to asc.
  • order_field: The name of the field on which to paginate. Supported fields are specific to each endpoint, and it’s not possible to specify any arbitrary name. See the documentation for each specific list endpoint to see which fields it supports. Defaults to id for most resources, and most only support id.

A typical paginated responses looks like this:

{
    "clusters": [
        ...
    ],
    "has_more": true,
    "next_cursor": "p56biajnfvgjhftvqs7lqymspe"
}

Pagination should follow these steps:

  1. Fetch the first page by omitting the cursor parameter initially.
  2. Consume all items on the current page. If has_more is true, pass the value of next_cursor as the cursor parameter to get the next page.
  3. Repeat step (2) until has_more is false (and/or next_cursor is null, which is functionally the same).

Note that not all list endpoints support pagination. Make sure to look in the API reference at the specific endpoint you’re trying to call to see if pagination parameters are present.

Rate limiting

Various actions in the API are rate limited to protect against client bugs, discourage abuse, and guarantee a stable platform for all users. The most common rate limit is number of allowed requests per second, but there may be others at play as well. Rate limited requests will get a 429 status code along with a more specific error message in the body (see errors) If the requests per second limit is hit, the API will respond with a Retry-After header containing the number of seconds the client should delay before trying again.

Rate limits are not guaranteed by API compatibility and may be subject to change. Well-behaved clients should be able to respect a returned 429 even if they encounter no rate limits today.

Request IDs

All API responses include an X-Request-Id header containing a UUID which uniquely fingerprints the request/response. Best practice is to log this value so that in case a problem is encountered, it can be provided to our support team who will then be able to easily identify the request in question.

Clients can also optionally generate their own request ID by sending X-Request-Id along with their request, which can be a better option in case of a problem where no response is received. Request IDs must be formatted as a valid UUID in common string format.

Unique identifiers

Almost all API resources will be uniquely identified by an id field in EID format. These IDs are stable, and unique across all accounts.