Clusters

The clusters endpoint allows you to retrieve information about clusters as well as provision new ones and delete existing clusters.

Prior to using any of these endpoints, take a look at the Getting Started section within the API reference to understand how to create your long lived API key and retrieve a short lived key to be able to execute operations against the API.

Listing clusters

Generic listing

The /clusters endpoint itself will list from the Personal team.

Status code: 200 OK

{
  "clusters": [
    {
      "id": "uan5fhajlzhjdnzmhgfp2d2umy",
      "team_id": "yqdhoxeognh67gby7wag7w5gem",
      "provider_id": "aws",
      "region_id": "us-east-1",
      "created_at": "2021-01-22T22:22:35.03991Z",
      "updated_at": "2021-01-22T22:22:35.03991Z",
      "name": "test-1",
      "major_version": 12,
      "storage": 100,
      "cpu": 2,
      "memory": 8,
      "is_ha": true
    },
    ...
    {
      "id": "j7bbo2gbd5davhkcuchsmsz3s4",
      "team_id": "yqdhoxeognh67gby7wag7w5gem",
      "provider_id": "aws",
      "region_id": "us-east-1",
      "created_at": "2021-01-28T00:14:37.898092Z",
      "updated_at": "2021-01-28T00:14:37.898092Z",
      "name": "test-3",
      "major_version": 13,
      "storage": 100,
      "cpu": 4,
      "memory": 16,
      "is_ha": false,
      "replicas": [
        {
          "id": "hw4j2fw33zgb3mx5lpoiosj3va",
          "team_id": "yqdhoxeognh67gby7wag7w5gem",
          "provider_id": "aws",
          "region_id": "us-east-1",
          "created_at": "2021-01-28T19:15:04.441902Z",
          "updated_at": "2021-01-28T19:15:04.441902Z",
          "name": "test-3-replica",
          "major_version": 13,
          "storage": 100,
          "cpu": 2,
          "memory": 8,
          "is_ha": false
        }
      ]
    }
  ]
}

Team-specific listing

To retrieve the list of clusters that exist for a specific team, you should hit the standard clusters endpoint followed by the team ID as a query parameter:

GET /clusters?team_id={team_id}

This will provide all clusters that exist within that team.

Status code: 200 OK

{
  "clusters": [
    {
      "id": "4ayzwodj6zh3nhkcere6u7byhe",
      "team_id": "roi5nqqoyvgt3k2ka3t5qmfvgy",
      "provider_id": "azure",
      "region_id": "westus",
      "created_at": "2021-01-28T19:51:02.646693Z",
      "updated_at": "2021-01-28T19:51:02.646693Z",
      "name": "team-cluster1",
      "major_version": 13,
      "storage": 100,
      "cpu": 4,
      "memory": 16,
      "is_ha": false
    },
    {
      "id": "rvf73a77ozfsvcttryebfrnlem",
      "team_id": "roi5nqqoyvgt3k2ka3t5qmfvgy",
      "provider_id": "azure",
      "region_id": "eastus2",
      "created_at": "2021-02-08T14:03:54.772274Z",
      "updated_at": "2021-02-08T14:03:54.772274Z",
      "name": "team-cluster2",
      "major_version": 13,
      "storage": 32,
      "cpu": 1,
      "memory": 4,
      "is_ha": false
    }
  ]
}

Clusters object

Attribute Type Description
id string Unique identifier for the cluster
team_id string Unique identifier for the team
provider_id string Unique identifier for provider
region_id string Unique identifier for region
created_at string Date/time of when the cluster was created, in RFC3339 format
updated_at string Date/time of when the cluster was last created, in RFC3339 format
name string Name of cluster
major_version integer PostgreSQL major version number
storage integer Storage in GB
cpu integer Number of vCores
memory integer Memory in GB
is_ha boolean Whether high availability is enabled for cluster
replicas array of objects Read replicas of cluster

Replicas object

The replicas object has the same attributes as the parent cluster object.

Retrieving cluster details

Details about a specific cluster can be retrieved using the GET /clusters/{cluster_id} endpoint.

Status code: 200 OK

{
  "id": "azpiatrcn5eujmhncap73ujeqm",
  "team_id": "eaevtjiudzeq7bsqbbpiscund4",
  "provider_id": "aws",
  "region_id": "us-east-1",
  "created_at": "2021-02-12T19:51:35.414479Z",
  "updated_at": "2021-01-30T19:51:35.414479Z",
  "name": "example-cluster",
  "major_version": 13,
  "storage": 1,
  "cpu": 1,
  "memory": 2,
  "is_ha": false
}

Provisioning a cluster

Clusters can be provisioned against the API:

POST /clusters

There are a number of required and a few optional fields when creating your cluster:

  • Name - text [required]
  • Team - Unique team identifier [required]
  • Plan - Unique plan identifier [required]
  • Storage - Integer in MB [required]
  • Provider - Unique provider identifier [required]
  • Region - Unique region identifier [required]
  • Version - Integer Postgres major version [required]
  • HA - Boolean to specify HA on or off (optional, default: false)

Refer to the Providers section for details on retrieving the unique identifiers for plans, providers, and regions.

An example request to create a cluster:

$ curl -X POST https://api.crunchybridge.com/clusters \
  -d '{
    "name": "staging",
    "team_id": "eaevtjiudzeq7bsqbbpiscund4",
    "plan_id": "hobby-2",
    "storage": 100,
    "provider_id": "aws",
    "region_id": "us-east-1",
    "major_version": 13
  }' -H "Authorization: Bearer lf6b76vzhzc2hhudyacj4aqlgy"

Status codes:

  • 201 Created. A new cluster is provisioned.
  • 400 Bad Request. The request contains an invalid value, for example a decimal value for major_version.
  • 409 Conflict. The request specifies a non-unique name (i.e. a cluster that already exists).

Retrieving cluster credentials

Usable credentials for a cluster are retrieved through the separate roles endpoint. Their retrieval should be needed less frequently than standard cluster information, so hosting them separately reduces the likelihood that they’ll be accidentally leaked.

GET /clusters/{cluster_id}/roles/{role_id}

Currently, only the default role is supported, so all requests will look like:

GET /clusters/{cluster_id}/roles/default

The default role is the cluster’s superuser, which can be used to add other users by way of standard SQL.

{
  "name": "postgres",
  "password": "Yodtp6pRYzUsqNeHFIDVS3ViS266l5WeifCkdsvdzosQ1jTBMvKJKYF7h0tuMHd7",
  "uri": "postgres://postgres:Y[email protected]p.33ddusyv3fgkrf2bz67bxlkpwa.db.postgresbridge.com:5432/postgres"
}

Forking a cluster

Clusters can be forked at point in time against the API. Required fields are the same for provisioning a new cluster with the addition of one optional field:

  • Target Time - the target point in time, in RFC3339 format [optional, default: now()]

The target time should be a time between the oldest_backup and now(). The oldest backup time can be obtained from the cluster details listing API endpoint. Note: If not oldest backup is listed, then a backup currently doesn’t not exist for the cluster. This is common shortly after a cluster is first created.

POST /clusters/{cluster_id}/forks

An example POST to fork a cluster:

$ curl -X POST https://api.crunchybridge.com/clusters/rvf73a77ozfsvcttryebfrnlem/forks \
  -d '{
    "is_ha": false,
    "name": "staging-fork",
    "plan_id": "hobby-2",
    "storage": 100,
    "provider_id": "aws",
    "region_id": "us-east-1",
    "target_time": "2009-11-10T23:00:00Z"
  }' -H "Authorization: Bearer lf6b76vzhzc2hhudyacj4aqlgy"

Status codes:

  • 201 Created. A new fork is provisioned.
  • 400 Bad Request. The request contains an invalid value, or a backup currently does not exist.

Deleting a cluster

DELETE /clusters/{cluster_id}

curl -X DELETE https://api.crunchybridge.com/clusters/rvf73a77ozfsvcttryebfrnlem -H "Authorization: Bearer lf6b76vzhzc2hhudyacj4aqlgy"

Status codes:

  • 204 No Content. The cluster is successfully deleted.

Managing cluster firewall rules

The API allows you to create, update, delete, and retrieve a list of firewall rules.

Currently, you can create, update, or delete one firewall rule per call.

Retrieving firewall rules

Pass in the cluster ID as a path parameter to the following endpoint:

GET /clusters/{cluster_id}/firewall

Status code: 200 OK

{
  "firewall_rules": [
    {
      "id": "rwhpndhwrfdetco3wypdyuw4vm",
      "rule": "0.0.0.0/0"
    }
  ]
}

Firewall rules object

Attribute Type Description
id string Unique identifier for the firewall rule
rule string Specific IP address or valid CIDR block (IPv4, IPv6)

Creating a firewall rule

POST /clusters/{cluster_id}/firewall

curl -X POST https://api.crunchybridge.com/clusters/rvf73a77ozfsvcttryebfrnlem/firewall \
  -d '{"rule":"0.0.0.0/0"}' -H "Authorization: Bearer lf6b76vzhzc2hhudyacj4aqlgy"

Status codes:

  • 201 Created. A new firewall rule is added.
  • 400 Bad Request. The request body contains invalid values (e.g. invalid IP address).
  • 409 Conflict. There is a conflict with an existing firewall rule.

Getting a firewall rule

Get a specific firewall rule by sending cluster and firewall rule IDs:

GET /clusters/{cluster_id}/loggers/{firewall_rule_id}

Status code: 200 OK

Updating a firewall rule

Use the PUT method and pass in the cluster ID and firewall rule ID as path parameters to the following endpoint:

PUT /clusters/{cluster_id}/firewall/{firewall_rule_id}

curl -X PUT https://api.crunchybridge.com/clusters/rvf73a77ozfsvcttryebfrnlem/firewall/6ulthse7k5gm7kxz4cqwojagki \
  -d '{"rule":"172.27.153.74/24"}' -H "Authorization: Bearer lf6b76vzhzc2hhudyacj4aqlgy"

Status codes:

  • 204 No Content. The specified firewall rule is updated.
  • 400 Bad Request. The request body contains invalid values (e.g. invalid IP address).

Deleting a firewall rule

DELETE /clusters/{cluster_id}/firewall/{firewall_rule_id}

curl -X DELETE https://api.crunchybridge.com/clusters/rvf73a77ozfsvcttryebfrnlem/firewall/wgv6v6damvahth3wb76ee4awsu \
  -H "Authorization: Bearer lf6b76vzhzc2hhudyacj4aqlgy"

Status codes:

  • 204 No Content. The firewall rule is successfully removed.

Configuring logging integration

Logging integrations can also be configured per cluster via the API.

Retrieving log destinations

Pass in the cluster ID as a path parameter to the following endpoint:

GET /clusters/{cluster_id}/loggers

This will return the log destinations configured for the cluster:

Status code: 200 OK

{
  "loggers": [
    {
      "id": "s3q3zqzdr5fqbgya7xupxxpyva",
      "host": "syslog-a.logdna.com",
      "port": 6514,
      "template": "<${PRI}>1 ${ISODATE} ${HOST} ${PROGRAM} ${PID} ${MSGID} [[email protected] key=\\\"MY-INGESTION-KEY\\\"] $MSG\\n",
      "description": "My description"
    }
  ]
}

Loggers object

Attribute Type Description
id string Unique identifier for the logger
host string Endpoint hostname
port integer Port number
template string Format for log messages
description string Description

Adding a log destination

POST /clusters/{cluster_id}/loggers

The hostname, port, template, and description are required to create a log destination:

curl -X POST "https://api.crunchybridge.com/clusters/zceucbf5pjgkjbnk3uwcbmmkei/loggers" -d '{"host":"syslog-a.logdna.com", "port": 6514, "template":"<${PRI}>1 ${ISODATE} ${HOST} ${PROGRAM} ${PID} ${MSGID} [[email protected] key=\\\"MY-INGESTION-KEY\\\"] $MSG\n", "description":"My description" }' -H "Authorization: Bearer lf6b76vzhzc2hhudyacj4aqlgy"

Status codes:

  • 201 Created. A new log destination is added.
  • 400 Bad Request. The request body is missing a required field, or contains an invalid or incorrectly formatted value.

Getting a log destination

Get a specific log destination by sending cluster and logger IDs:

GET /clusters/{cluster_id}/loggers/{logger_id}

Status code: 200 OK

Editing a log destination

Pass in the cluster ID and logger ID to the following endpoint:

PUT /clusters/{cluster_id}/loggers/{logger_id}

Host, port, template, and description values are all required.

curl -X PUT "https://api.crunchybridge.com/clusters/zceucbf5pjgkjbnk3uwcbmmkei/loggers/s3q3zqzdr5fqbgya7xupxxpyva" -d '{"description":"My updated description", "host":"syslog-a.logdna.com", "port": 6514, "template":"<${PRI}>1 ${ISODATE} ${HOST} ${PROGRAM} ${PID} ${MSGID} [[email protected] key=\\\"MY-INGESTION-KEY\\\"] $MSG\n" }' -H "Authorization: Bearer lf6b76vzhzc2hhudyacj4aqlgy"

Status codes:

  • 204 No Content. The specified log destination is updated.
  • 400 Bad Request. The request body is missing a required field, or contains an invalid or incorrectly formatted value.

Deleting a log destination

DELETE /clusters/{cluster_id}/loggers/{logger_id}

curl -X DELETE "https://api.crunchybridge.com/clusters/zceucbf5pjgkjbnk3uwcbmmkei/loggers/s3q3zqzdr5fqbgya7xupxxpyva" -H "Authorization: Bearer lf6b76vzhzc2hhudyacj4aqlgy"

Status codes:

  • 204 No Content. The log destination is successfully removed.

Resizing a cluster

The resize API can be used to change a cluster’s plan or the amount of storage it has.

Starting a resize

Start a resize:

POST /clusters/{cluster_id}/resize

At least one of the following parameters is required:

  • Plan ID (plan_id) - Plan ID.
  • Storage (storage) - New disk size in GB.
curl -X POST "https://api.crunchybridge.com/clusters/zceucbf5pjgkjbnk3uwcbmmkei/resize" -d '{"plan_id":"standard-64", "storage": 100}' -H "Authorization: Bearer lf6b76vzhzc2hhudyacj4aqlgy"

This will return the log destinations configured for the cluster:

Status codes:

  • 201 Created. A new log destination is added.
  • 400 Bad Request. The request body is missing a required field, or contains an invalid or incorrectly formatted value.
{
  "status": "resizing"
}

Resize object

Attribute Type Description
state string Current state of the resize. One of scheduled, resizing, or failing_over. null if no resize is in progress.

Retrieving resize status

Get the current status of a resize:

GET /clusters/{cluster_id}/resize

curl -X GET "https://api.crunchybridge.com/clusters/zceucbf5pjgkjbnk3uwcbmmkei/resize" -H "Authorization: Bearer lf6b76vzhzc2hhudyacj4aqlgy"

Status code: 200 OK

Canceling a resize

Cancel an in progress resize:

DELETE /clusters/{cluster_id}/resize

curl -X DELETE "https://api.crunchybridge.com/clusters/zceucbf5pjgkjbnk3uwcbmmkei/resize" -H "Authorization: Bearer lf6b76vzhzc2hhudyacj4aqlgy"

Status codes:

  • 204 No Content. The resize was successfully canceled.