Reference¶
Every operation in the API, generated from the same specification the API's own tests check. Paths are relative to https://dashboard.breqwatr.cloud. The OpenAPI file is the same document, for generating a client.
Each operation lists the errors specific to it. Authentication failures, rate limits and restricted organisations apply throughout, and the Errors guide has the format of every error.
Billing¶
GET /api/v1/orgs/{org_id}/invoices¶
Invoices (owners and admins)
Input parameters
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
cursor |
query | string | No | next_cursor from the previous page |
limit |
query | integer | No | Page size, 1 to 100 (default 50) |
org_id |
path | string | Yes | |
project_id |
query | string | No | Only this project's invoices |
Responses
every invoice but drafts, newest first
{
"data": [
{
"id": "c41e8b07-2fd6-49a3-b1e8-5d06a7c3f912",
"invoice_number": "INV-1001",
"billing_period": "2026-09",
"status": "sent",
"project_id": "a9d27e10-64b3-4f18-8c05-71e3f6ab20d9",
"project_name": "web",
"issued_at": "2026-10-01T00:00:00Z",
"due_date": "2026-10-31",
"autopay": false,
"currency": "CAD",
"subtotal": 10000,
"discount": 0,
"credit_applied": 0,
"tax_label": "HST",
"tax_rate": "0.1300",
"tax": 1300,
"total": 11300
}
],
"next_cursor": null
}
manager_required: a member
GET /api/v1/orgs/{org_id}/invoices/{id}¶
One invoice, with its line items, or its PDF
Input parameters
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | string | Yes | |
org_id |
path | string | Yes |
Responses
the invoice and its line items (Accept: application/pdf returns the PDF)
{
"data": {
"id": "c41e8b07-2fd6-49a3-b1e8-5d06a7c3f912",
"invoice_number": "INV-1001",
"billing_period": "2026-09",
"status": "sent",
"project_id": "a9d27e10-64b3-4f18-8c05-71e3f6ab20d9",
"project_name": "web",
"issued_at": "2026-10-01T00:00:00Z",
"due_date": "2026-10-31",
"autopay": false,
"currency": "CAD",
"subtotal": 10000,
"discount": 0,
"credit_applied": 0,
"tax_label": "HST",
"tax_rate": "0.1300",
"tax": 1300,
"total": 11300
}
}
{
"data": {
"id": "c41e8b07-2fd6-49a3-b1e8-5d06a7c3f912",
"invoice_number": "INV-1001",
"billing_period": "2026-09",
"status": "sent",
"project_id": "a9d27e10-64b3-4f18-8c05-71e3f6ab20d9",
"project_name": "web",
"issued_at": "2026-10-01T00:00:00Z",
"due_date": "2026-10-31",
"autopay": false,
"currency": "CAD",
"subtotal": 10000,
"discount": 0,
"credit_applied": 0,
"tax_label": "HST",
"tax_rate": "0.1300",
"tax": 1300,
"total": 11300
}
}
not_found: no such invoice, or a draft
GET /api/v1/orgs/{org_id}/projects/{project_id}/usage¶
A project's billed usage for a month (owners and admins)
Input parameters
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
month |
query | integer | No | 1 to 12, defaults to this month |
org_id |
path | string | Yes | |
project_id |
path | string | Yes | |
year |
query | integer | No | Defaults to this year |
Responses
the month's lines by section, subscriptions, subtotal and total
{
"data": {
"period_start": "2022-04-13",
"period_end": "2022-04-13",
"currency": "string",
"line_items": [
{
"section": "compute",
"resource_name": "web-1",
"description": "m1.small",
"region": "yul1",
"hours": 720.0,
"start_at": "2026-09-01T00:00:00Z",
"end_at": "2026-09-30T23:59:00Z",
"cost": 10000
}
],
"subscriptions": [
{
"kind": "string",
"name": "string",
"description": "string",
"cost": 0
}
],
"subtotal": 0,
"total": 0
}
}
invalid_period: not a calendar month
manager_required: a member
Account¶
GET /api/v1/me¶
The caller and the token in use
Input parameters
| Parameter | In | Type | Required | Description |
|---|
Responses
the caller
{
"data": {
"id": "5fa77358-b061-425b-92a4-d778c7d080ec",
"name": "string",
"email": "string",
"timezone": "string",
"created_at": "2022-04-13T15:42:05.901Z",
"token": {
"id": "0f6e774e-b336-4e36-9a20-e1579d56dde3",
"name": "string",
"prefix": "string",
"organisation_id": "7682bcdf-6885-4b2c-9798-23a241f01e8a",
"expires_at": "2022-04-13T15:42:05.901Z",
"created_at": "2022-04-13T15:42:05.901Z"
}
}
}
invalid_token: missing, invalid or revoked; token_expired: past its expiry
Members¶
PATCH /api/v1/orgs/{org_id}/members/{id}¶
Change a member's role or project access
Input parameters
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | string | Yes | |
org_id |
path | string | Yes |
Request body
Schema of the request body
{
"type": "object",
"properties": {
"role": {
"type": "string",
"enum": [
"owner",
"admin",
"member"
],
"description": "Owner only. owner transfers ownership; you become an admin"
},
"project_ids": {
"type": "array",
"items": {
"type": "string",
"format": "uuid"
},
"description": "Owners and admins, member-role memberships, while per-project access is on"
}
},
"example": {
"role": "admin"
}
}
Responses
the updated member
bad_request: neither role nor project_ids; invalid_parameter: an unknown role, or a project outside this organisation
owner_required: anyone but the owner changing a role; manager_required: a member changing project access
own_membership: your own membership; per_project_access_off: per-project access is off; not_member_role: project access applies to the member role only
DELETE /api/v1/orgs/{org_id}/members/{id}¶
Remove a member (owners and admins)
Input parameters
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | string | Yes | |
org_id |
path | string | Yes |
Responses
removed
manager_required: a member; owner_required: an admin removing an owner
own_membership: your own membership; last_owner: the organisation's only owner
GET /api/v1/orgs/{org_id}/members/{id}¶
One member
Input parameters
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | string | Yes | |
org_id |
path | string | Yes |
Responses
POST /api/v1/orgs/{org_id}/invitations¶
Invite someone (owners and admins)
Input parameters
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
Idempotency-Key |
header | string | No | Retrying with the same key returns the original response instead of creating again |
org_id |
path | string | Yes |
Request body
Schema of the request body
{
"type": "object",
"required": [
"email",
"role"
],
"properties": {
"email": {
"type": "string"
},
"role": {
"type": "string",
"enum": [
"member",
"admin"
]
},
"project_ids": {
"type": "array",
"items": {
"type": "string",
"format": "uuid"
},
"description": "Only while per-project access is on"
}
},
"example": {
"email": "new@example.com",
"role": "member"
}
}
Responses
the invitation, emailed to them, or with its link while email is off
invalid_parameter: a role other than member or admin, or project_ids that do not apply
manager_required: a member
already_member, invitation_pending (already invited) or account_unclaimed (an account not yet set up)
GET /api/v1/orgs/{org_id}/invitations¶
Pending invitations (owners and admins)
Input parameters
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
cursor |
query | string | No | next_cursor from the previous page |
limit |
query | integer | No | Page size, 1 to 100 (default 50) |
org_id |
path | string | Yes |
Responses
GET /api/v1/orgs/{org_id}/members¶
The organisation's members
Input parameters
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
cursor |
query | string | No | next_cursor from the previous page |
limit |
query | integer | No | Page size, 1 to 100 (default 50) |
org_id |
path | string | Yes |
Responses
Audit¶
GET /api/v1/orgs/{org_id}/audit_events¶
The organisation's audit log (owners and admins)
Input parameters
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
action_type |
query | string | No | Only this action, e.g. project.created |
cursor |
query | string | No | next_cursor from the previous page |
limit |
query | integer | No | Page size, 1 to 100 (default 50) |
org_id |
path | string | Yes |
Responses
audit events, newest first, through the whole history
manager_required: a member, not an owner or admin
Organisations¶
GET /api/v1/orgs¶
The organisations you belong to
Input parameters
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
cursor |
query | string | No | next_cursor from the previous page |
limit |
query | integer | No | Page size, 1 to 100 (default 50) |
Responses
GET /api/v1/orgs/{id}¶
One organisation you belong to
Input parameters
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | string | Yes |
Responses
the organisation, with your role
org_suspended, billing_setup_required or billing_details_incomplete
not_found: not an organisation you belong to
Projects¶
POST /api/v1/orgs/{org_id}/projects¶
Create a project (owners and admins)
Answers before the project is ready. Read Location until its default region's status is ready or failed.
Input parameters
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
Idempotency-Key |
header | string | No | Retrying with the same key returns the original response instead of creating again |
org_id |
path | string | Yes |
Request body
Responses
created; its default region provisions in the background, so poll it until ready
Response headers
| Name | Description | Schema |
|---|---|---|
Location |
Where to read the project | string |
manager_required: a member; billing_details_incomplete: finish the billing details first
trial_project_limit: a free trial's project limit is reached
validation_failed: see errors; idempotency_key_reused: that key was used for a different request
GET /api/v1/orgs/{org_id}/projects¶
The projects you can see in an organisation
Input parameters
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
cursor |
query | string | No | next_cursor from the previous page |
limit |
query | integer | No | Page size, 1 to 100 (default 50) |
org_id |
path | string | Yes |
Responses
a page of projects, every status, with where each is provisioned
{
"data": [
{
"id": "a9d27e10-64b3-4f18-8c05-71e3f6ab20d9",
"name": "web",
"description": "Storefront",
"status": "active",
"created_at": "2026-09-14T15:04:05Z",
"monthly_budget": 50000,
"regions": [
{
"region": "yul1",
"status": "ready"
},
{
"region": "yyz1",
"status": "pending"
}
]
}
],
"next_cursor": null
}
not_found: not an organisation you belong to
PATCH /api/v1/orgs/{org_id}/projects/{id}¶
Edit a project, or archive it
Input parameters
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | string | Yes | |
org_id |
path | string | Yes |
Request body
Schema of the request body
{
"type": "object",
"properties": {
"name": {
"type": "string"
},
"description": {
"type": "string",
"nullable": true
},
"monthly_budget": {
"type": "integer",
"nullable": true,
"description": "Minor units (cents); null clears it"
},
"status": {
"type": "string",
"enum": [
"archived"
],
"description": "Archives the project (owner only)"
}
},
"example": {
"name": "storefront",
"monthly_budget": 50000
}
}
Responses
the updated project
invalid_parameter: a budget that is not whole cents, or any status but archived
manager_required: a member editing; owner_required: anyone but the owner archiving
DELETE /api/v1/orgs/{org_id}/projects/{id}¶
Delete a project (owner only)
Answers before the project is gone. Read the project until it answers 404.
Input parameters
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | string | Yes | |
org_id |
path | string | Yes |
Responses
marked deleting and torn down in the background; it then reads as gone
owner_required: only the owner can delete a project
deletion_blocked: instances or volumes remain; blocker, count and region say which
cloud_unavailable: a region could not be checked; nothing was changed
Response headers
| Name | Description | Schema |
|---|---|---|
Retry-After |
Seconds to wait before trying again | integer |
GET /api/v1/orgs/{org_id}/projects/{id}¶
One project
Input parameters
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | string | Yes | |
org_id |
path | string | Yes |
Responses
the project
not_found: not a project you can see
POST /api/v1/orgs/{org_id}/projects/{project_id}/regions/{region_id}/provisioning¶
Provision a project in a region, or retry a failed run
Input parameters
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
org_id |
path | string | Yes | |
project_id |
path | string | Yes | |
region_id |
path | string | Yes | Keystone region id |
Responses
provisioning; poll the project's regions until this one is ready or failed
not_found: an unknown or disabled region
project_not_ready: the project is still being created
Quotas¶
POST /api/v1/orgs/{org_id}/projects/{project_id}/quota_increase_requests¶
Request more quota in a region (owners and admins)
Input parameters
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
Idempotency-Key |
header | string | No | Retrying with the same key returns the original response instead of creating again |
org_id |
path | string | Yes | |
project_id |
path | string | Yes |
Request body
Schema of the request body
{
"type": "object",
"required": [
"region",
"reason",
"add"
],
"properties": {
"region": {
"type": "string",
"description": "Keystone region id"
},
"reason": {
"type": "string"
},
"add": {
"type": "object",
"description": "Amounts to add to the current limits, each a positive whole number",
"properties": {
"ram_gb": {
"type": "integer"
},
"storage_gb": {
"type": "integer"
},
"instances": {
"type": "integer"
},
"vcpus": {
"type": "integer"
},
"floating_ips": {
"type": "integer"
}
}
}
},
"example": {
"region": "yul1",
"reason": "Two new storefronts",
"add": {
"ram_gb": 64
}
}
}
Responses
the request, holding the limits asked for
Response headers
| Name | Description | Schema |
|---|---|---|
Location |
Where to read the request | string |
invalid_parameter: an unknown dimension, or an amount that is not a positive whole number
manager_required: a member
validation_failed: nothing requested, or a request already open in that region; idempotency_key_reused: that key was used for a different request
GET /api/v1/orgs/{org_id}/projects/{project_id}/quota_increase_requests¶
A project's quota increase requests, every region
Input parameters
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
cursor |
query | string | No | next_cursor from the previous page |
limit |
query | integer | No | Page size, 1 to 100 (default 50) |
org_id |
path | string | Yes | |
project_id |
path | string | Yes |
Responses
requests, newest first
PATCH /api/v1/orgs/{org_id}/projects/{project_id}/quota_increase_requests/{id}¶
Resubmit a request staff sent back for more information
Input parameters
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | string | Yes | |
org_id |
path | string | Yes | |
project_id |
path | string | Yes |
Request body
Schema of the request body
{
"type": "object",
"required": [
"reason",
"add"
],
"properties": {
"reason": {
"type": "string"
},
"add": {
"type": "object",
"description": "Amounts to add to the current limits, each a positive whole number",
"properties": {
"ram_gb": {
"type": "integer"
},
"storage_gb": {
"type": "integer"
},
"instances": {
"type": "integer"
},
"vcpus": {
"type": "integer"
},
"floating_ips": {
"type": "integer"
}
}
}
},
"example": {
"reason": "Two new storefronts",
"add": {
"ram_gb": 32
}
}
}
Responses
resubmitted, pending review again
manager_required: a member
not_editable: staff have not sent it back
GET /api/v1/orgs/{org_id}/projects/{project_id}/quota_increase_requests/{id}¶
One quota increase request
Input parameters
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | string | Yes | |
org_id |
path | string | Yes | |
project_id |
path | string | Yes |
Responses
the request, with any review note
not_found: not a request on this project
GET /api/v1/orgs/{org_id}/projects/{project_id}/regions/{region_id}/quota¶
A project's quota and usage in one region
Input parameters
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
org_id |
path | string | Yes | |
project_id |
path | string | Yes | |
region_id |
path | string | Yes | Keystone region id |
Responses
used and limit for each dimension; a null limit is unlimited
not_found: an unknown or disabled region
quota_unavailable: the cloud's quota could not be read just now
Response headers
| Name | Description | Schema |
|---|---|---|
Retry-After |
Seconds to wait before trying again | integer |
Regions¶
GET /api/v1/regions¶
The regions you can choose between
Input parameters
| Parameter | In | Type | Required | Description |
|---|
Responses
Schemas¶
audit_event¶
| Name | Type | Description |
|---|---|---|
action |
string | Stable action code, e.g. project.created |
actor |
string | |
created_at |
string(date-time) | |
description |
string | |
id |
string(uuid) | |
project_id |
string(uuid) | null |
invitation¶
| Name | Type | Description |
|---|---|---|
created_at |
string(date-time) | |
email |
string | |
expires_at |
string(date-time) | |
id |
string(uuid) | |
role |
string | One of: owner, admin, member |
url |
string | The invitation link, only while email delivery is off |
invoice¶
| Name | Type | Description |
|---|---|---|
autopay |
boolean | null | |
billing_period |
string | |
credit_applied |
integer | |
currency |
string | |
discount |
integer | |
due_date |
string(date) | null | |
id |
string(uuid) | |
invoice_number |
string | |
issued_at |
string(date-time) | null | |
line_items |
Array<line_item> | |
project_id |
string(uuid) | null | |
project_name |
string | |
status |
string | One of: sent, paid, void |
subtotal |
integer | Minor units (cents) |
tax |
integer | |
tax_label |
string | null | |
tax_rate |
string | Decimal string, e.g. "0.1300" |
total |
integer |
line_item¶
| Name | Type | Description |
|---|---|---|
cost |
integer | Minor units (cents) |
description |
string | null | |
end_at |
string(date-time) | null | |
hours |
number | null | |
region |
string | null | Keystone region id |
resource_name |
string | null | |
section |
string | compute, volumes, snapshots, floating_ips, ... |
start_at |
string(date-time) | null |
member¶
| Name | Type | Description |
|---|---|---|
email |
string | |
id |
string(uuid) | Membership id |
joined_at |
string(date-time) | |
name |
string | |
project_access |
Only while per-project access is on. "all" for owners and admins; for a member, the granted project ids to an owner or admin, a count to anyone else. | |
role |
string | One of: owner, admin, member |
organisation¶
| Name | Type | Description |
|---|---|---|
created_at |
string(date-time) | |
id |
string(uuid) | |
name |
string | |
role |
string | One of: owner, admin, member |
slug |
string | |
status |
string | One of: pending, active, suspended |
problem¶
| Name | Type | Description |
|---|---|---|
blocker |
string | deletion_blocked only: the kind of resource in the way |
code |
string | Stable; match on this One of: account_unclaimed, already_member, bad_request, billing_details_incomplete, billing_setup_required, cloud_unavailable, deletion_blocked, idempotency_key_in_progress, idempotency_key_reused, internal_error, invalid_cursor, invalid_parameter, invalid_period, invalid_token, invitation_pending, last_owner, manager_required, not_editable, not_found, not_member_role, org_suspended, own_membership, owner_required, per_project_access_off, project_not_ready, quota_unavailable, rate_limited, token_expired, trial_project_limit, validation_failed |
count |
integer | deletion_blocked only: how many of them remain |
detail |
string | |
errors |
Array<Properties: field, message> |
validation_failed only: what to fix, per field |
region |
string | deletion_blocked only: the Keystone region id they are in |
request_id |
string | Also sent as X-Request-Id; quote it to support |
status |
integer | |
title |
string | |
type |
string | A URI naming the problem |
project¶
| Name | Type | Description |
|---|---|---|
created_at |
string(date-time) | |
description |
string | null | |
id |
string(uuid) | |
monthly_budget |
integer | null | Minor units (cents); owners and admins only |
name |
string | |
regions |
Array<Properties: region, status> |
The default region first, then each region the project has been opened in |
status |
string | One of: active, suspended, archived, deleting |
quota¶
| Name | Type | Description |
|---|---|---|
dimensions |
Properties: ram_gb, storage_gb, instances, vcpus, floating_ips |
|
provisioned |
boolean | false: the project has not been used in this region yet; limits are the profile it will start from |
region |
string | Keystone region id |
quota_increase_request¶
| Name | Type | Description |
|---|---|---|
created_at |
string(date-time) | |
id |
string(uuid) | |
reason |
string | null | |
region |
string | Keystone region id |
requested |
Properties: ram_gb, storage_gb, instances, vcpus, floating_ips |
The limit asked for in each dimension the request touches |
review_note |
string | null | |
status |
string | One of: pending, approved, rejected, needs_info |
updated_at |
string(date-time) |
region¶
| Name | Type | Description |
|---|---|---|
default |
boolean | |
id |
string | Keystone region id |
name |
string |