Swyftstack REST API
A predictable, org-scoped REST API for managed PostgreSQL, object storage and backups. Authenticate with an API key or connect an AI client with device login. Everything the console does, you can automate.
On this page: Authentication · Scopes · Rate limits · Errors · Pagination · Endpoints · Examples · Workflows
Overview
The base URL is below. Every response is JSON in a { data } envelope; errors use { error: { code, message } }. All timestamps are ISO-8601 UTC. IDs are prefixed public ids (db_…, proj_…, bucket_…).
https://swyftstack.com/v1https://swyftstack.com/api/v1 is an exact alias for the same API and is supported permanently - use whichever you prefer. Both accept identical paths, methods and headers.
Authentication
Send your API key as a bearer token on every request.
Authorization: Bearer sk_live_your_key_hereDevice authentication (recommended for AI/CLI)
AI clients connect without a key using the OAuth 2.0 Device Authorization Grant (RFC 8628). The client calls POST /v1/device/authorize, shows you a short code, and polls POST /v1/device/token; you approve in the browser at /device and a scoped key is minted automatically. The official MCP server does this for you - see the MCP guide.
API keys (scripts & CI)
Create long-lived keys under Settings → API keys, with a scope preset and optional expiry. The secret is shown once. Keys are org-scoped and can be revoked anytime.
OAuth 2.0 (roadmap)
A full three-legged OAuth flow for third-party apps is on the roadmap. Today, use device login (for AI/CLI) or API keys (for your own automation).
Scopes
Each key is limited to the scopes you grant. Scopes marked destructive additionally require the key's dangerous-operations toggle.
| Database | database:createdatabase:readdatabase:updatedatabase:delete ⚠ |
| Storage | storage:createstorage:readstorage:updatestorage:delete ⚠ |
| Backups | backup:createbackup:restorebackup:delete ⚠backup:downloadbackup:list |
| Account | account:read |
| Billing | billing:read |
| Teams | team:read |
⚠ = destructive. Presets: Read Only (view resources, usage, and backups. cannot create, change, or delete anything.) · Developer (create and manage databases, buckets, and backups. no destructive deletes.) · Full Access (every scope, including deletes (deletes still require the dangerous-operations toggle).)
Rate limits, errors & pagination
Rate limits
Every request passes three nested ceilings, so no single project, key, or account can crowd out the rest:
- 1,000 requests/minute per API key, per project - requests not tied to a project (
/v1/account/*,/v1/agent/*, list endpoints) share one bucket of the same size for the key. - 3,000 requests/minute per API key across all projects.
- 6,000 requests/minute per organization across all API keys.
Expensive or irreversible operations (create database, create/restore backup, create bucket, import) have tighter per-key limits on top of that. Exceeding any limit returns 429 with a Retry-After header. Every response also carries X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset (unix seconds), so a client can pace itself before it is refused.
Error responses
{
"error": {
"code": "insufficient_scope",
"message": "This API key is missing the required scope: database:create."
}
}Codes: unauthorized (401), forbidden / insufficient_scope / dangerous_not_allowed (403), not_found (404), conflict (409), validation_error (422), rate_limited (429), internal_error (500).
Pagination
List endpoints accept ?limit= (max 100). Log endpoints also accept ?page= and return meta.has_next. Results are newest-first.
Endpoints
A key can only see and act on resources in its own organization.
Projects
| GET | /v1/projects | account:read | List projects |
| GET | /v1/projects/:id | account:read | Get a project |
| POST | /v1/projects | account:read + database:create | Create a project (databases and buckets live inside one) |
Databases
| GET | /v1/databases | database:read | List databases |
| POST | /v1/databases | database:create | Create a database |
| GET | /v1/databases/:id | database:read | Get a database |
| DELETE | /v1/databases/:id | database:delete | Delete a database (destructive) |
| POST | /v1/databases/:id/restart | database:update | Restart |
| POST | /v1/databases/:id/pause | database:update | Pause |
| POST | /v1/databases/:id/resume | database:update | Resume a paused database |
| POST | /v1/databases/:id/rotate-password | database:update | Rotate password |
| GET | /v1/databases/:id/connection | database:read | Connection details |
| GET | /v1/databases/:id/metrics | database:read | Metrics (?hours=) |
| GET | /v1/databases/:id/ssl | database:read | SSL/TLS status |
Network & security
| PUT | /v1/databases/:id/ssl | database:update | Require TLS (or revert to prefer) |
| GET | /v1/databases/:id/allowlist | database:read | Get IP allow-list |
| PUT | /v1/databases/:id/allowlist | database:update | Replace IP allow-list |
| GET | /v1/databases/:id/rls | database:read | Row-Level Security overview |
| POST | /v1/databases/:id/rls | database:update | Enable/disable RLS on a table |
Backups & restore
| GET | /v1/databases/:id/backups | backup:list | List backups |
| POST | /v1/databases/:id/backups | backup:create | Trigger a manual backup |
| POST | /v1/databases/:id/backups/:backupId/restore | backup:restore | Restore from a backup |
| POST | /v1/databases/:id/backups/:backupId/pin | backup:create | Pin/unpin a backup |
| DELETE | /v1/databases/:id/backups/:backupId | backup:delete | Delete a backup (destructive) |
| GET | /v1/databases/:id/export | backup:download | Latest downloadable export |
| GET | /v1/databases/:id/recovery | backup:list | Point-in-time recovery status |
| POST | /v1/databases/:id/recovery/restore-request | backup:restore | Request a point-in-time restore |
Imports
| GET | /v1/imports | database:read | List imports |
| POST | /v1/imports | database:create | Import an external database |
| GET | /v1/imports/:importId | database:read | Import status + log |
Storage
| GET | /v1/buckets | storage:read | List buckets |
| POST | /v1/buckets | storage:create | Create a bucket |
| GET | /v1/buckets/:id | storage:read | Get a bucket |
| DELETE | /v1/buckets/:id | storage:delete | Delete a bucket (destructive) |
| PUT | /v1/buckets/:id/visibility | storage:update | Make a bucket public or private |
| POST | /v1/buckets/:id/public-url | storage:read | Get an object's public URL |
| GET | /v1/buckets/:id/objects | storage:read | List objects |
| POST | /v1/buckets/:id/objects?key=… | storage:update | Upload an object (raw bytes or JSON envelope) |
| DELETE | /v1/buckets/:id/objects/:key | storage:delete | Delete an object |
Account & agent
| GET | /v1/account/usage | account:read | Usage vs plan limits |
| GET | /v1/account/limits | account:read | Plan limits + features |
| GET | /v1/account/billing | billing:read | Billing + trial state |
| GET | /v1/account/api-keys | account:read | List API keys |
| GET | /v1/account/audit-logs | account:read | API + agent activity log |
| GET | /v1/agent/status | account:read | AI-optimized account snapshot |
| GET | /v1/agent/recommendations | account:read | Actionable recommendations |
Examples
Create a database, in four languages.
curl -X POST https://swyftstack.com/v1/databases \ -H "Authorization: Bearer $SWYFTSTACK_API_KEY" \ -H "Content-Type: application/json" \ -d '{"project":"proj_xxx","name":"production"}'
Common workflows
- Create a database:
POST /v1/databases, thenGET /v1/databases/:id/connectionfor the URL. - Import a database:
POST /v1/imports, then pollGET /v1/imports/:importId. - Restore a backup:
GET /v1/databases/:id/backups→POST /v1/databases/:id/backups/:backupId/restore. - Manage storage:
POST /v1/buckets, thenPOST /v1/buckets/:id/objects?key=…to upload. - Rotate a password:
POST /v1/databases/:id/rotate-password(returns fresh credentials once). - View usage:
GET /v1/account/usageor the aggregatedGET /v1/agent/status. - Manage API keys: list with
GET /v1/account/api-keys; create/revoke in the dashboard.