Skip to content

Public API

The Public API exposes two endpoints for the audit log:

Both accept the same filters and require the project owner or an admin member.


Authenticate

Requests use an access token from the OAuth 2.0 client credentials flow, with the Cloud API credentials of the project whose log you want to read:

ACCESS_TOKEN=$(curl -s -X POST https://api.verda.com/v1/oauth2/token \
  -H 'Content-Type: application/json' \
  -d '{"grant_type":"client_credentials","client_id":"<CLIENT_ID>","client_secret":"<CLIENT_SECRET>"}' \
  | jq -r .access_token)

The project is taken from the credentials, so no project id is needed in the request.


Read events

curl -G https://api.verda.com/v1/audit/log \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -d object_type=compute \
  -d action=delete \
  -d page_size=100

The response holds the events in data and, when more pages remain, a cursor:

{
  "data": [
    {
      "specversion": "1.0",
      "id": "log_033FNaNcc0AtphhH71DLBW",
      "source": "https://api.verda.com/project/7c9e6a41-2f8b-4d3e-9a15-0b6c4d2e8f37",
      "subject": "7bdb4161-c7d2-478c-9850-05719adc8381",
      "type": "com.verda.api.cloud.compute.delete.v1",
      "time": "2026-07-28T14:15:52.872Z",
      "data": {
        "contract": "PAY_AS_YOU_GO",
        "hostname": "tiny-tree-unfolds-fin-01",
        "instance_type": "CPU.4V.16G",
        "location_code": "FIN-01",
        "discontinue_reason": "by_user_action",
        "request_ip": "203.0.113.10",
        "request_origin": "console-11.67.0",
        "actor_id": "5bbb59cb-fced-44a4-85c6-5005e7480a8f",
        "compute": {
          "id": "7bdb4161-c7d2-478c-9850-05719adc8381",
          "hostname": "tiny-tree-unfolds-fin-01",
          "instance_type": "CPU.4V.16G",
          "ip": "192.0.2.15",
          "os_volume_id": "2b7d0e2e-fc8d-4e9c-8b89-6117a4d8d941",
          "location_code": "FIN-01",
          "is_cluster": false
        }
      }
    }
  ],
  "cursor": "log_02yTr8Kc11BspqLM40XZQV"
}

Query parameters

  • object_type=compute: return events for one object type, for example compute, volume, ssh_key, user. See supported events.
  • action=delete: return events for one action, for example create, delete, login.
  • start_date=2026-07-01T00:00:00.000Z: events at or after this timestamp. Cannot be more than 90 days ago. Defaults to 90 days ago.
  • end_date=2026-07-31T00:00:00.000Z: events at or before this timestamp. Cannot be before start_date.
  • page_size=100: events per page, from 1 to 100. Defaults to 20.
  • cursor=log_02yTr8Kc11BspqLM40XZQV: continue from the cursor returned by the previous response.

Page through the log

This endpoint uses cursor pagination rather than the page and pageSize parameters used elsewhere in the API. Pass the cursor from each response back in the next request. The last page has no cursor.

Because the order is fixed (newest first, by event time), events written while you page do not shift the ones you have already read.

import requests

URL = "https://api.verda.com/v1/audit/log"
headers = {"Authorization": f"Bearer {access_token}"}
params = {"object_type": "compute", "page_size": 100}

events = []
while True:
    response = requests.get(URL, headers=headers, params=params, timeout=60)
    response.raise_for_status()
    page = response.json()

    events.extend(page["data"])
    cursor = page.get("cursor")
    if not cursor:
        break
    params["cursor"] = cursor
# first page
curl -G https://api.verda.com/v1/audit/log \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -d page_size=100

# next page, using the cursor from the previous response
curl -G https://api.verda.com/v1/audit/log \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -d page_size=100 \
  -d cursor=log_02yTr8Kc11BspqLM40XZQV

Exporting to a JSON file

POST /v1/audit/log/download takes the same filters as the read endpoint, without page_size and cursor. Verda writes every matching event to a file in object storage and returns a pre-signed link to it:

curl -X POST https://api.verda.com/v1/audit/log/download \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"object_type":"compute","start_date":"2026-07-01T00:00:00.000Z"}'
{
  "url": "https://objects.fin-03.verda.storage/audit-logs/7c9e6a41-2f8b-4d3e-9a15-0b6c4d2e8f37/2026/audit-log-20260730-141552-3f0c9a71-b08f-4d48-9e03-6ab6196c186b.json?X-Amz-Signature=...",
  "expires_at": "2026-07-30T14:30:52.872Z"
}

Download it with any HTTP client, no extra credentials needed:

curl -o audit-log.json "<url from the response>"
  • The file is a single JSON array of the same event objects the read endpoint returns, newest first.
  • The link is valid for 15 minutes, until expires_at. Request a new export once it expires.
  • Each export writes a new file, so exporting twice with the same filters gives you two links.
  • The file is written before the response comes back. For a busy project, filter by date range or object type to keep the export small and the request short.

Errors

Status Reason
400 start_date is more than 90 days ago, or end_date is before start_date
401 The access token is missing or expired
403 The credentials belong to a developer member rather than the project owner or an admin member