Your first API call
This page covers every convention the Platform DataBank API follows. Once you've read it, the full reference is a flat list of endpoints with schemas — no further surprises.
1. Base URL
Each tenant gets its own API origin derived from its primary hostname. If you're a direct Platform DataBank customer, that's https://api.platformdb.services . Resellers expose their own origin per their branded domain.
Every endpoint in the reference is relative to /api/v1, so a call to /client/invoices becomes {BASE_URL}/api/v1/client/invoices .
2. Authentication
Mint an API key in your client portal under Settings → API keys → New key. The raw key is shown once at creation time; only its Argon2id hash is stored server-side. Send it as a bearer token:
Authorization: Bearer pdb_live_xxxxxxxxxxxxxxxxxxxxxxxxKeys are scoped to the organisation of the user who created them — a key cannot access any org other than its issuer's. Revoking a key at the portal takes effect immediately for all subsequent requests.
3. Scopes
Each key carries one or more scopes chosen at creation. A request that requires a scope the key lacks returns 403 FORBIDDEN. The full list:
| Scope | Grants |
|---|---|
| * | Wildcard. Grants every scope below. Use sparingly. |
| subscriptions:read | Read subscription metadata + status. |
| subscriptions:power | Power on / off / reboot virtual machines. |
| invoices:read | Read invoices and invoice PDFs. |
| tickets:read | Read support tickets. |
| tickets:create | Open new tickets and reply on existing ones. |
| projects:read | Read project (colo deployment) metadata. |
| status:read | Read platform + component status and incidents. |
| servers:read | Read dedicated servers: live status, bandwidth, sensors, IPs, rDNS. |
| servers:write | Dedicated server actions: power, OS reinstall, rescue mode, rDNS edits. |
| tags:read | Read the org’s tags and tag assignments. |
| tags:write | Create, assign, and remove tags. |
Prefer narrow scopes over *. Keys can be rotated by creating a new one and revoking the old — there's no edit-scope mutation mid-life.
4. Rate limits
Each key has a per-minute sliding-window limit (default 60 req / min; contact support for higher ceilings). On overage the API returns 429 RATE_LIMITED with a Retry-After header (seconds) and a body carrying the same value in details.retryAfterSec . Respect the header; aggressive retrying will trip key throttling.
5. Pagination
Every list endpoint accepts page (1-based) and limit (max 100) query params and returns:
{
"data": [ /* array of rows */ ],
"pagination": {
"page": 1,
"limit": 20,
"total": 137,
"totalPages": 7
}
}Results are ordered newest-first unless an endpoint documents otherwise.
6. Error shape
Errors are JSON with three fields:
{
"error": "human-readable message",
"code": "UPPER_SNAKE_CONSTANT",
"details": { /* optional structured context */ }
}Common codes:
| Code | HTTP | Meaning |
|---|---|---|
| UNAUTHENTICATED | 401 | Missing / invalid API key. |
| FORBIDDEN | 403 | Key exists but lacks the required scope. |
| NOT_FOUND | 404 | Resource does not exist or is out of scope. |
| VALIDATION_ERROR | 422 | Request body / params failed schema. |
| CONFLICT | 409 | State transition not allowed (e.g. already paid). |
| RATE_LIMITED | 429 | Retry after the value in `Retry-After`. |
| INTERNAL_ERROR | 500 | Unexpected server failure. Retry with backoff. |
7. Idempotency
Safe-by-design endpoints — power actions, payment charge, ticket reply — treat repeat requests with the same logical effect as no-ops. The platform does not currently require an Idempotency-Key header; mutation endpoints return the current state after the change, so callers can detect a redundant request by comparing the response to what they expected.
Planned: Idempotency-Key on invoice-pay and new-ticket endpoints so a retried network call never double-charges or double-files. Watch the reference — any endpoint that accepts the header will document it.
8. Webhooks
Subscribe to platform events (invoice finalized, ticket updated, VM state change, etc.) by registering an endpoint via POST /client/webhooks . Each event is POSTed as JSON with an X-Pdb-Signature HMAC-SHA256 over the raw body using the secret returned at registration. Rotate the secret via the rotate-secret mutation — previous secrets invalidate immediately.
Delivery is retried with exponential backoff on 5xx / network errors for up to 24 hours. The /client/webhooks/:id/deliveries endpoint returns the recent attempt log. A test-fire endpoint lets you confirm your receiver without waiting for a real event.
