No matching sections.
Account, usage & quota
Four reads on account:read that answer the questions a client asks
before it acts - what is this account allowed to do, how much of it has it already done, and how many API
calls are left - and one write on account:write that changes the account's own
details.
| Operation | Answers |
|---|---|
GET /account | Everything below in one document - identity, flags, package, usage, limits, badges. |
GET /account/usage | Just the consumption block. |
GET /account/quota | API-call headroom, and the mintable scope catalogue. |
GET /account/member | The contacts holding shared access to this account. |
PATCH /account | Change the account's own details - name, company, phone, country, time zone, language, default monitoring locations. Scope account:write. |
GET /account
{
"id": "3fa85f64-…",
"login": "acme",
"timezone": "Etc/UTC",
"language": "it",
"profile": {
"firstName": "QA29437", "lastName": "", "company": "",
"phone": "", "country": "", "email": "[email protected]"
},
"defaultAgentPools": { "legacy": ["allworld"] },
"flags": { "enabled": true, "active": true, "overlimited": false, "apiEnabled": false },
"package": { "id": "…", "name": "30-Days Free Trial", "features": { /* … */ } },
"usage": { "monitor": { "used": 14, "allowed": 100 }, /* contact, report, maintenance */ },
"overlimits": [],
"limits": { "intervals": [60, 120, 180, /* 14 total */], "maxBulkItems": 5000, /* … */ },
"badges": { "unconfirmedContacts": 0, "alerts24h": 0, "openIncidents": 0 }
}
This account is on the 30-Days Free Trial, whose package does not sell API access - hence
flags.apiEnabled: false above; see flags below for why that is
informational, not a gate. flags.disableReason and
flags.stoppedAt are themselves omitted here rather than sent as
null - both apply only to a disabled/stopped account, and this one is neither.
badges is the dashboard's attention row, readable programmatically: contacts still
waiting for confirmation, alerts delivered in the last 24 hours, and currently-open incidents.
flags: the account's own state
flags is a bag of independent booleans, not a lifecycle:
enabled, active and
overlimited, plus disableReason and
stoppedAt when they apply. Any combination can hold at once, which is precisely why
it is not one word.
state until 2026-08-17. On this surface
state means one position in a lifecycle - a monitor's, a job's, an incident's - and
a bag of independent booleans is not that. There is no alias: the old member is simply absent.
apiEnabled tells you whether this account may use the API at all. It is
true when the package sells API access and the account's API policy is not
negative - the same predicate the token mint runs. It never blocks a read: an account
without it still gets its 200 and its (usually empty) quota document, which is
exactly the state that used to be indistinguishable from a bug. What it cannot do is mint a token. ⚠ The
mint also refuses while the account is suspended, and that is published separately as
flags.active - so the honest client-side test for "can I mint a token" is
apiEnabled && active. The two are kept apart on purpose: folded into one
boolean, "why is my API off" stops being answerable.
overlimits beside it says which dimensions are over -
task, contact, report,
maintenance - and is empty when the account is inside its package. So
flags.overlimited tells you that, and
overlimits tells you what.
profile and default locations
profile is who the account is registered to, and
defaultAgentPools is where a new monitor starts checking from. Both ride
GET /account and both are written by
PATCH /account - so a client reads the resource, edits it,
and sends it back without ever leaving this endpoint.
| Member | Meaning |
|---|---|
profile.firstName / lastName | The account holder's name. At most 50 characters each. |
profile.company | The organisation. At most 100 characters. |
profile.phone | A contact number, stored as typed and never parsed as a number. At most 20 characters. |
profile.country | An ISO 3166-1 alpha-2 code - DE, US. |
profile.email | The login address. Read-only here - changing it is a confirmation-code flow on the sign-in surface, not a resource write. |
timezone / language | On the object root, not inside profile - where they have been since this endpoint shipped. Both are writable. |
defaultAgentPools | The monitoring locations a new monitor of each service type starts with, keyed by service type and valued with pool ids, agent ids, or an agent id prefixed - to exclude it. |
"" when they are not set, never as
null - they sit on columns that cannot hold null. That is also what makes
"" the way to clear one. email is the exception and
can be null.
defaultAgentPools is keyed by the service type's lowercase token -
net, waterfall, internal,
legacy, meta - the same spelling
GET /agent/pool publishes its
defaults under. It is the same map, and one fact gets one vocabulary. A PascalCase
key (Net) is refused outright: 422
unknown_enum_value with reason: unknown_service_type and the accepted
tokens listed in allowed.
PATCH /account
Changes the members the body names and leaves the rest alone. Answers 200 with the whole updated
account - the same document GET /account returns - so nothing has to be
re-read to confirm what was written. Scope account:write; a delegated member
needs the profile-edit right. Idempotency-Key is accepted and not required.
A minimal patch, changing three members:
{
"company": "Acme Ltd",
"country": "GB",
"timezone": "Europe/London"
}
Reads back with the whole account - the touched members updated, and timezone
already in its IANA spelling:
{
"id": "3fa85f64-…",
"login": "acme",
"timezone": "Europe/London",
"profile": {
"firstName": "QA29437", "lastName": "", "company": "Acme Ltd",
"phone": "", "country": "GB", "email": "[email protected]"
},
/* language, defaultAgentPools, flags, package, usage, overlimits, limits, badges - unchanged, same shape as GET /account above */
}
| Member | Rules |
|---|---|
firstName / lastName / company / phone | Trimmed; 50 / 50 / 100 / 20 characters. "" clears. |
country | An ISO 3166-1 alpha-2 code, matched against the platform's own country list. "" clears. An unknown code is 422 unknown_enum_value with reason: unknown_country. |
timezone | A time-zone id - the IANA spelling (Europe/Berlin) or the Windows one; either is accepted and the IANA form is what reads back. There is no "no zone" state - send "UTC" rather than an empty value. |
language | One of the languages the platform actively translates; matched case-insensitively and stored in the roster's own spelling. Anything else is 422 unknown_enum_value with reason: unknown_language and the accepted list in allowed. |
defaultAgentPools | The whole map, or null to clear every default. Each id is validated against the same location catalogue a monitor write uses. |
defaultAgentPools REPLACES the map - it does not merge into it. Send the
map you want the account to end up with: a body naming only waterfall leaves the
account with a waterfall default and no others. null clears every default and a
type mapped to [] clears that one. This is the same rule every nested object
member on this surface follows, and merging would make "remove my net default"
inexpressible.
"" means clear; null on a
text field is refused. Those columns cannot hold null, so null answers
422 validation_failed with reason: wrong_type and a
detail pointing at the empty string. An empty body is a legal no-op: 200, nothing written.
422 unknown_pool pointing at the exact element
(/defaultAgentPools/net/1) with the selectable pools in
valid. A save that silently discards half of what you sent and still answers
200 is the failure mode this surface refuses everywhere.
package and features
package.features is the entitlement map: booleans and numeric caps, camelCase, and
exactly the names a 403 package_limit problem puts in its
feature field. That is the point of the shared spelling - a refusal names
a key you can look up here, rather than prose you have to map by hand.
usage: what you have spent
GET /account/usage - and the identical block on
GET /account - reports consumption per domain under four
singular keys, each {used, allowed}:
{
"monitor": { "used": 14, "allowed": 100 },
"contact": { "used": 3, "allowed": 20 },
"report": { "used": 0, "allowed": null }, // null = no limit
"maintenance": { "used": 1, "allowed": 0 } // 0 = a real cap of none
}
allowed: null means "no limit". allowed: 0 means a
real cap of none. They are different answers and a client must not collapse them. The keys were
plural and the no-limit sentinel was -1 until 2026-08-17: any arithmetic on
that sentinel - a progress bar, a "% used" figure, a pre-flight check - read an unlimited dimension as an
already-breached cap. null cannot be arithmetic'd by accident.
limits: what a request may ask for
Where usage is about your rows, limits is about your
requests - the numbers a client needs before it composes one:
| Member | Meaning |
|---|---|
intervals | The check intervals this account may set. Read it instead of hardcoding - a value outside it is 422 invalid_interval, and that refusal echoes this same list in allowed. |
alertDelays | The alert delays a subscription may use, same deal. |
maxBulkItems / maxBulkSelection | How many items one bulk submission carries, and how large a filter-matched selection may be. |
maxLimit / defaultLimit | The paging bounds - what ?limit= accepts, and what it is when omitted. |
maxInlineContacts | How many contacts[] one POST /monitor may carry. |
monitor / contact | The same bulk numbers again, per domain, where a domain differs from the account-wide figure. |
quota: API call headroom
GET /account/quota reports how many API calls are left, without spending
any of them. When at least one window is configured, its top-level
limit/used/remaining/
resetAt describe the tightest-binding window - the one you will hit
first. On an account with none configured - like the capture below - those members, each pool's own
limit, and tokenCap are omitted
rather than sent as null, the same omit-when-absent rule
flags.disableReason/stoppedAt follow above. And
pools breaks it down:
{
"pools": {
"check": { "quotas": [] }, // instant checks
"account": { "quotas": [] } // everything else
},
"scopes": [ { "scope": "monitor:read", "description": "…" }, /* 20 rows */ ],
"apiEnabled": false
}
Each entry of a pool's quotas[] is one configured window:
| Member | Meaning |
|---|---|
scope | Which scope the window applies to. |
quota | Which quota this is - requests-per-minute, checks-per-month, and so on. |
limit / used / remaining | The window's arithmetic. |
resetAt / windowSec | When used returns to zero, and how long the window is. |
successOnly | True when only SUCCESSFUL requests count - a 4xx/5xx does not spend the quota. It changes how you should read remaining, so it is stated rather than assumed. |
quotas: [] is not a bug. It is what "no window is configured for this
account" looks like on the wire - and on such an account ordinary calls carry no
RateLimit-* headers either, and no
429 quota_exceeded. The anonymous reference tier is metered separately, per client
address; see Authentication & scopes.
scopes[] is the mintable scope catalogue - all 20 (thirteen
leaves plus seven families), each with a one-line description from the source registry. Build a token-scope
picker from it rather than from a hardcoded list. tokenCap echoes the presented
token's own self-cap when it carries one.
apiEnabled repeats GET /account's
flags.apiEnabled here, because this is the document you read when you are asking
"may I, and how much" - and those two halves should not cost two calls. false
beside an empty pools means "the API is not enabled for this account", which is a
different statement from "this account is not metered".
Shared access
GET /account/member lists the contacts holding shared access to this account -
the subaccount graph, read-only here:
| Member | Meaning |
|---|---|
id | The membership row's id, which is the contact the access was granted to - the key the whole subaccount graph is stored under. |
userId | The delegate's own account id, once the invitation has been accepted. Null before that. |
contact | The minimal identifying projection of the contact. |
rights | The granted rights as <area>:<read|write> tokens - monitor:write, contact:read, billing:read, profile:write, api:access, member:write, statusPage:read. Sorted, so two reads of the same grant are byte-equal. |
state | active | pending (invited, not yet confirmed) | disabled. |
rights are not API token scopes, even where the words rhyme. A right
governs what a delegated person may do in the account; a scope governs what a token may do.
api:access is the right that lets a member use the API at all - and their calls are
then bounded by their own token's scopes as well.