Account, edges and keys¶
Your accounts and their branding, the default posture for new vServices, the edges that serve your vServices, and the key you call with. API keys, team members and delegations are managed only in the portal, signed in: see API access and Team and delegation.
Endpoints¶
| Method | Path | Key | Purpose |
|---|---|---|---|
GET |
/accounts |
read | Your accounts |
GET |
/accounts/{account_id} |
read | One account |
PUT |
/accounts/{account_id} |
write | Change an account's name and branding |
POST |
/accounts/{account_id}/logo |
write | Upload a logo |
GET |
/edges |
read | Edges that serve your vServices |
GET |
/edges/{name} |
read | One edge |
GET |
/tenant |
read | Your tenant |
PATCH |
/tenant |
write | Set the default posture for new vServices |
GET /accounts
Returns: 200, AccountList
Answer 200
[
{
"account_id": "acc-a",
"tenant": "tenant-a",
"name": null,
"plan": "dedicated",
"services": [
"a.example.com",
"deleg.example.com",
"tcp.example.com"
],
"created": null
}
]
GET /accounts/{account_id}
Returns: 200, Account
Answer 200
{
"account_id": "acc-a",
"tenant": "tenant-a",
"plan": "dedicated",
"created_by": "",
"branding": {},
"services": [
"a.example.com",
"deleg.example.com",
"tcp.example.com"
]
}
PUT /accounts/{account_id}
Body: AccountUpdate
Returns: 200, Account
Request
{
"name": "Shop",
"branding": {
"primary_color": "#009FE3"
}
}
Answer 200
{
"account_id": "acc-a",
"tenant": "tenant-a",
"name": "Shop",
"plan": "dedicated",
"acme_email": null,
"branding": {
"primary_color": "#009FE3",
"background_color": "#f5f5f5",
"logo_file": null,
"support_email": null,
"support_url": null,
"pow_text": null,
"block_text": null,
"error_titles": {},
"error_messages": {}
},
"created": "",
"created_by": "",
"services": [
"a.example.com",
"deleg.example.com",
"tcp.example.com"
]
}
POST /accounts/{account_id}/logo
Body (form upload): LogoUpload
Returns: 200, LogoStored
Answer 200
{
"filename": "logo.png",
"path": "accounts/acc-a/assets/logo.png"
}
GET /edges
Returns: 200, EdgeList
Answer 200
[
{
"name": "shared-1",
"display_name": "Frankfurt 1",
"site": "fra",
"location": "Frankfurt",
"status": "healthy",
"last_seen": "2026-10-22T14:00:00.500000+00:00",
"config_sha": "abc",
"puller_version": "2.2.38",
"edgemon_version": "2.1.18",
"scrubd_version": "0.1.57",
"flowd_version": "0.1.11",
"tenant": null,
"dedicated": false
}
]
GET /edges/{name}
Returns: 200, Edge
Answer 200
{
"name": "shared-1",
"display_name": "Frankfurt 1",
"site": "fra",
"location": "Frankfurt",
"status": "healthy",
"last_seen": "2026-10-22T14:00:00.500000+00:00",
"config_sha": "abc",
"puller_version": "2.2.38",
"edgemon_version": "2.1.18",
"scrubd_version": "0.1.57",
"flowd_version": "0.1.11",
"tenant": null,
"dedicated": false
}
GET /tenant
Returns: 200, Tenant
Answer 200
{
"tenant": "tenant-a",
"company_name": "A",
"portal_name": null,
"portal_domain": null,
"default_posture": "standard",
"dedicated_edges": [],
"ip_pools": []
}
PATCH /tenant
Body: TenantPatch
Returns: 200, TenantPosture
Request
{
"default_posture": "standard"
}
Answer 200
{
"default_posture": "standard"
}
| Method | Path | Key | Purpose |
|---|---|---|---|
GET |
/keys/me |
read | The calling key |
GET /keys/me
Returns: 200, Key
Answer 200
{
"id": "TGloIsNcCavQ",
"tenant": "tenant-a",
"owner": {
"kind": "account"
},
"label": "ci",
"scopes": [
"protect:read",
"protect:write"
],
"allowed_ips": [
"1.2.3.4",
"2a00:1450:4001::1"
],
"expires_at": "2026-11-22T00:00:00Z",
"created_by": "owner@tenant-a.example",
"created_at": "2026-10-23T10:13:25Z",
"revoked_at": null,
"revoked_by": null
}
Fields¶
Key¶
| Field | Type | Notes |
|---|---|---|
id |
string | Key id: the 12 characters after zsk_ |
tenant |
string | Your tenant id |
label |
string | Name given to the key at creation |
owner |
object | Who the key belongs to |
scopes |
list of string | protect:read allows GET; protect:write allows everything else |
allowed_ips |
list of string | The only client addresses the key works from: single IPv4 or IPv6 addresses |
expires_at |
string | When the key stops working |
created_by |
string | E-mail of the person who created the key |
created_at |
string | When the key was created |
revoked_at |
string | may be null; When the key was revoked; null while it is not |
revoked_by |
string | may be null; Who revoked the key; null while it is not revoked |
Account¶
| Field | Type | Notes |
|---|---|---|
account_id (required) |
string | Account id |
tenant (required) |
string | Your tenant id |
name |
string | may be null; Display name; null when none is set |
plan |
string | one of shared, dedicated, byoip; may be null; dedicated and byoip create vServices themselves; null = shared |
acme_email |
string | may be null; Contact for the certificate authority |
branding |
Branding |
Branding of the error and maintenance pages of the account's vServices |
created |
string | may be null; When the account was created; null when not recorded |
created_by |
string | Your e-mail or key label; empty = Zero Services |
services (required) |
list of string | FQDNs of the account's vServices |
AccountUpdate¶
| Field | Type | Notes |
|---|---|---|
name |
string | up to 100 characters; may be null; Display name; null or empty clears it |
branding |
Branding |
Merged into the stored branding: send only what changes |
Tenant¶
| Field | Type | Notes |
|---|---|---|
tenant (required) |
string | Your tenant id |
company_name |
string | may be null; Your company name |
portal_name |
string | may be null; Name of your white-label portal; null without one |
portal_domain |
string | may be null; Domain of your white-label portal; null without one |
default_posture (required) |
string | one of off, standard, under_attack; Posture of vServices created from now on |
dedicated_edges |
list of object | Edges dedicated to you, the choices for POST /services |
ip_pools |
list of object | Your pools, the choices for POST /services; empty without a dedicated or BYOIP account |
Edge¶
| Field | Type | Notes |
|---|---|---|
name (required) |
string | Hostname of the edge |
display_name |
string | Readable name of the edge |
site |
string | Site the edge belongs to |
location |
string | Location code from the edge's hostname, such as fra |
status (required) |
string | one of healthy, degraded, config_outdated, maintenance, error, unknown; healthy: every check passes. config_outdated: runs an older configuration, for less than a minute. degraded: monitoring silent, configuration behind for longer, last reload failed, or WAF or BGP down. maintenance: taken out by Zero Services. error: no report for 5 minutes, or HAProxy down. unknown: never reported |
last_seen |
string | may be null; Time of the edge's last report |
config_sha |
string | may be null; Config revision the edge runs |
puller_version |
string | may be null; Installed version of the puller, which applies the configuration; null when not installed |
edgemon_version |
string | may be null; Installed version of edgemon, the edge's monitoring agent; null when not installed |
scrubd_version |
string | may be null; Installed version of scrubd, the layer 3/4 packet filter; null when not installed |
flowd_version |
string | may be null; Installed version of flowd, the flow statistics at the site boundary; null when not installed |
tenant |
string | may be null; Your tenant on an edge dedicated to you, null on a shared edge |
dedicated |
boolean | The edge is dedicated to you |
Example¶
Which key is this, and which edges serve my vServices:
curl -s -H "Authorization: Bearer $ZP_KEY" $API/keys/me
curl -s -H "Authorization: Bearer $ZP_KEY" $API/edges
Behaviour¶
GET /keys/meshows the calling key's scopes, bound addresses (allowed_ips) and expiry; a key created by a delegation member hasowner.kinddelegation.- A delegation key sees only the delegated vServices and the edges that serve them; branding and the default posture for new vServices are not available to it.
- The default posture for new vServices stays with the primary account.
- Branding: the edges' error, challenge and maintenance pages show your colours, logo,
support_emailandsupport_url;pow_textis the challenge headline,block_textwhat the block page (403) says happened,error_titlesanderror_messagesper status. Empty texts keep the page's own. Logo: PNG, JPEG or WebP, up to 24 KB (it is inlined into the pages), no SVG. GET /edgeslists the edges that serve at least one of your vServices, with status and last report; with no vService placed yet, the list is empty.
In the portal: ZERO-PROTECT → API keys, Team, Edge Nodes.