API

Webhooks

Open certain actions taking place within your account, we can trigger a JSON POST callback to a URL or your choice, containing resource ID and event name. For example:

{
  "event": "instance.created",
  "resourceID": "84894d17-da88-45bb-8817-9b3b75cf61bf"
}

Webhook Lifecycle

Your Webhook handlers are expected to respond within 5 seconds. If they take longer than this, then the failures count will be incremented and the webhook queued for reprocessing. Reprocessing happens at 5 minutes, 30 minutes, 1 hour, 2 hours, 6 hours - and after that the webhook will be disabled.

Payload Headers

The headers of the request from our servers will contain the following two important headers: X-Civo-Event and X-Civo-Signature. X-Civo-Event is a UUID that is unique to this event. We don't track them ourside, but retries of the same event will have the same ID, so you can track it and not process it twice.

X-Civo-Signature is an OpenSSL HMAC SHA1 digest of the entire payload using either the secret of the webhook. The secret is randomly generated when the webhook is created if one isn't specified. A simple example of how to calculate this in Ruby would be:

signature = OpenSSL::HMAC.hexdigest(
  OpenSSL::Digest.new('sha1'),
  webhook.secret,
  request.body
)

The following events are available to subscribe to:

NameDescription
*Any event happens
instance.createdAfter an instance has been requested to be built
instance.deletedWhen the instance has been requested to be deleted
instance.firewall.updatedWhen the firewall is requested to be updated for an instance
instance.rebootedWhen an instance has been requested to reboot
instance.resizedAfter an instance has been resized
instance.startedWhen an instance is requested to start (note: not when it's completed booting up and all daemons running)
instance.stoppedWhen an instance is requested to stop(note: not when it's finished shutting down)
instance.tags.updatedWhen an instance's tags have changed
domain.createdAfter a domain name has been added to our DNS service
domain.updatedAfter a domain name has been updated to our DNS service
domain.deletedAfter a domain has been removed from our DNS service
domain_record.createdAfter a DNS record has been added for a domain in our DNS service
domain_record.deletedAfter a DNS record has been removed for a domain from our DNS service
domain_record.updatedAfter a DNS record has been changed for a domain in our DNS service
firewall.createdAfter a firewall is created
firewall.updatedAfter a firewall is updated
firewall.deletedAfter a firewall is deleted
firewall_rule.createdAfter a rule is added to a firewall
firewall_rule.deletedAfter a rule is removed from a firewall
kubernetes_cluster.createdAfter a Kubernetes cluster is initially created
kubernetes_cluster.deletedAfter a Kubernetes cluster is initially created
kubernetes_cluster.updatedAfter a Kubernetes cluster has been updated(Name, Version or Applications)
kubernetes_cluster_pool.updatedAfter the number of nodes in a Kubernetes cluster has scaled up or down
kubernetes_cluster_node.recycledAfter the number of nodes in a Kubernetes cluster has scaled up
network.createdAfter a network is added
network.updatedAfter a network is updated
network.deletedAfter a network is removed
ip.createdAfter a ip is created
ip.updatedAfter a ip is updated
ip.deletedAfter a ip is deleted
ssh_key.createdAfter an SSH key has been uploaded to our site
ssh_key.updatedAfter an SSH key has been changed
ssh_key.deletedAfter an SSH key has been deleted
volume.createdAfter a volume has been created
volume.updatedAfter a volume has been updated
volume.deletedAfter a volume has been removed
volume.attachedAfter a volume has been attached
volume.detachedAfter a volume has been detached
volume.resizeAfter a volume has been resized
app.createdAn app has been created
app.deletedAn app has been deleted
objectstore.createdAfter a objectstore is created
objectstore.updatedAfter a objectstore is updated
objectstore.deletedAfter a objectstore is deleted
objectstorecredential.createdAfter an objectstorecredential is created
objectstorecredential.updatedAfter an objectstorecredential is updated
objectstorecredential.deletedAfter an objectstorecredential is deleted
subnet.createdAfter a subnet is added
subnet.deletedAfter a subnet is removed
database.createdAfter a database is initially created
database.updatedAfter a database has been updated
database.deletedAfter a database is deleted
database.restoredAfter a database is restored
databasebackup.createdAfter a database backup is initially created
databasebackup.updatedAfter a database backup has been updated
databasebackup.deletedAfter a database backup is deleted

Listing webhooks

Listing the webhooks is possible by making a GET request to the https://api.civo.com/v2/webhooks resource.

Request

This request doesn't take any parameters.

Response

The response from the server will be a JSON array of webhooks.

[
    {
        "id": "20f54d3e-6de8-4074-a1a7-8715e0ad5295",
        "created_at": "2021-09-08T09:01:28.000+01:00",
        "events": [
            "*"
        ],
        "url": "https://example.com",
        "secret": "foobar",
        "disabled": false,
        "failures": 0,
        "last_failure_reason": ""
    }
]

Example of listing webhooks

curl -H "Authorization: bearer 12345" https://api.civo.com/v2/webhooks
// At a shell prompt run:
// npm init -y
// npm i --save request

var request = require('request');

request.get(
  'https://api.civo.com/v2/webhooks',
  {},
  function (error, response, body) {
    if (!error && response.statusCode == 200) {
      console.log(body)
    }
  }
).auth(null, null, true, '12345');
require 'net/http'

http = Net::HTTP.new('api.civo.com', 443)
http.use_ssl = true

headers = {
  'Authorization' => 'bearer 12345',
  'Content-Type' => 'application/x-www-form-urlencoded'
}

resp, data = get('v2/webhooks', headers)

Create a new webhook

Any user can create webhooks for their account.

New webhooks are created by sending a POST request to https://api.civo.com/v2/webhooks.

Request

The required parameters are listed below.

Name Description
url (required) this is the URL to send the webhook to
events (optional) this is a list of events that the webhook should be triggered for (default is *)
secret (optional) this is if you want to specify your own secret, if not a random one will be created for you

Response

The response is a JSON representation of the webhook, including the secret.

{
    "result": "success",
    "id": "a1381788-a669-4f7f-9d30-d1d83d4d7ebd"
}

Example of creating a webhook

curl -H "Authorization: bearer 12345" https://api.civo.com/v2/webhooks \
  -F events='["*"]' -F url=https://api.example.com/webhook
// At a shell prompt run:
// npm init -y
// npm i --save request

var request = require('request');

request.post(
  'https://api.civo.com/v2/webhooks',
  {
    "events": ["*"],
    "url": "https://api.example.com/webhook"
  },
  function (error, response, body) {
    if (!error && response.statusCode == 200) {
      console.log(body)
    }
  }
).auth(null, null, true, '12345');
require 'net/http'

http = Net::HTTP.new('api.civo.com', 443)
http.use_ssl = true

headers = {
  'Authorization' => 'bearer 12345',
  'Content-Type' => 'application/x-www-form-urlencoded'
}

safe_url = CGI::escape("https://api.example.com/webhook")
resp, data = http.post('/v2/webhooks', 'events=["*"]&url=' + safe_url, headers)

Test a webhook

Once a webhook is created, you can test it by sending a POST request to https://api.civo.com/v2/webhooks/:id/test and this will call your webhook handler with a random resource ID and the first event the webhook was registered for. If the event is *, then we will send a random event name.

Request

No parameters are required for this request.

Response

The response is a JSON object that simply confirms that the request to test the webhook was received.

{
  "result": "success"
}

Example of testing a webhook

curl -H "Authorization: bearer 12345" -X POST https://api.civo.com/v2/webhooks/12345/test
// At a shell prompt run:
// npm init -y
// npm i --save request

var request = require('request');

request.post(
  'https://api.civo.com/v2/webhooks/12345/test',
  {},
  function (error, response, body) {
    if (!error && response.statusCode == 200) {
      console.log(body)
    }
  }
).auth(null, null, true, '12345');
require 'net/http'

http = Net::HTTP.new('api.civo.com', 443)
http.use_ssl = true

headers = {
  'Authorization' => 'bearer 12345',
  'Content-Type' => 'application/x-www-form-urlencoded'
}

resp, data = http.post('/v2/webhooks/12345/test', '', headers)

Update a webhook

After creating a webhook, any user can update it.

Webhooks are updated by sending a PUT request to https://api.civo.com/v2/webhooks/:id.

Request

Name Description
url (optional) this is the URL to send the webhook to
events (optional) this is a list of events that the webhook should be triggered for (default is *)
secret (optional) this is if you want to specify your own secret, if not a random one will be created for you

Response

The response is a JSON representation of the updated webhook, including the secret.

{
  "id": "b8de2e4e-72f4-4911-83ee-f4fc030fc4a2",
  "created_at": "2021-09-08T09:09:32.000+01:00",
  "events": ["*"],
  "url": "https://api.example.com/webhook",
  "secret": "DfeFUON8gorc5Zj0hk4GT1M9QImnRL6J",
  "disabled": false,
  "failures": 0,
  "last_failure_reason": "",
}

Example of updating a webhook

curl -H "Authorization: bearer 12345" -X PUT https://api.civo.com/v2/webhooks/12345 \
  -F events='["instance.created"]'
// At a shell prompt run:
// npm init -y
// npm i --save request

var request = require('request');

request.put(
  'https://api.civo.com/v2/webhooks/12345',
  {
    "events": ["instance.created"]
  },
  function (error, response, body) {
    if (!error && response.statusCode == 200) {
      console.log(body)
    }
  }
).auth(null, null, true, '12345');
require 'net/http'

http = Net::HTTP.new('api.civo.com', 443)
http.use_ssl = true

headers = {
  'Authorization' => 'bearer 12345',
  'Content-Type' => 'application/x-www-form-urlencoded'
}

resp, data = http.put('/v2/webhooks/12345', 'events=["instance.created"]', headers)

Deleting a webhook

An account holder can remove one of their webhooks by sending a DELETE request to https://api.civo.com/v2/webhooks/:id.

Request

This request takes no parameters, only the ID of the webhook to delete is in the URL. No confirmation step is required, this step will remove the webhook immediately.

Response

The response from the server will be a JSON block. The response will include a result field and the HTTP status will be 200 OK.

{
  "result": "success"
}

Example of deleting a webhook

curl -H "Authorization: bearer 12345" \
  -X DELETE https://api.civo.com/v2/webhooks/12345
// At a shell prompt run:
// npm init -y
// npm i --save request

var request = require('request');

request.del(
  'https://api.civo.com/v2/webhooks/12345',
  function (error, response, body) {
    if (!error && response.statusCode == 202) {
      console.log(body)
    }
  }
).auth(null, null, true, '12345');
require 'net/http'

http = Net::HTTP.new('api.civo.com', 443)
http.use_ssl = true

headers = {
  'Authorization' => 'bearer 12345',
  'Content-Type' => 'application/x-www-form-urlencoded'
}

resp, data = http.delete('/v2/webhooks/12345', headers)