Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

API Reference

RESTful API for Postbase Cloud platform.

Base URL

https://api.postbase.sh

Authentication

All API requests require a Bearer token:

Authorization: Bearer <access_token>

Get your token via CLI:

postbase cloud login
# Token stored in ~/.postbase/cloud.json

Response Format

All responses follow this structure:

{
  "success": true,
  "data": { ... }
}

Error responses:

{
  "success": false,
  "error": {
    "code": "ERROR_CODE",
    "message": "Human-readable error message"
  }
}

Rate Limits

TierRequests/minuteBurst
Free6010
Pro1000100

API Endpoints

Health Check

GET /
Response:
{
  "name": "Postbase Cloud API",
  "version": "0.5.2",
  "status": "healthy"
}

Authentication

Start Device Flow

POST /auth/device

Initiates GitHub OAuth device flow.

Response:
{
  "device_code": "abc123...",
  "user_code": "ABCD-1234",
  "verification_uri": "https://github.com/login/device",
  "expires_in": 900,
  "interval": 5
}

Poll for Token

POST /auth/device/token
Content-Type: application/json
 
{
  "device_code": "abc123..."
}
Response (pending):
{
  "status": "pending"
}
Response (success):
{
  "access_token": "pb_xxx...",
  "token_type": "Bearer",
  "user": {
    "id": "user_xxx",
    "github_id": 12345,
    "login": "username",
    "email": "user@example.com"
  }
}

Get Current User

GET /auth/me
Authorization: Bearer <token>
Response:
{
  "id": "user_xxx",
  "github_id": 12345,
  "login": "username",
  "email": "user@example.com",
  "created_at": "2026-01-20T10:00:00Z"
}

Projects

List Projects

GET /projects
Authorization: Bearer <token>
Response:
{
  "projects": [
    {
      "id": "proj_xxx",
      "name": "myapp",
      "created_at": "2026-01-20T10:00:00Z"
    }
  ]
}

Create Project

POST /projects
Authorization: Bearer <token>
Content-Type: application/json
 
{
  "name": "myapp"
}
Response:
{
  "id": "proj_xxx",
  "name": "myapp",
  "created_at": "2026-01-20T10:00:00Z"
}

Get Project

GET /projects/:id
Authorization: Bearer <token>

Delete Project

DELETE /projects/:id
Authorization: Bearer <token>

Databases

List Databases

GET /projects/:project_id/databases
Authorization: Bearer <token>
Response:
{
  "databases": [
    {
      "id": "db_xxx",
      "name": "production",
      "railway_service_id": "srv_xxx",
      "region": "us-west1",
      "status": "running",
      "created_at": "2026-01-20T10:00:00Z"
    }
  ]
}

Provision Database

POST /projects/:project_id/databases
Authorization: Bearer <token>
Content-Type: application/json
 
{
  "name": "production",
  "region": "us-west1",
  "config": {
    "cpu": 2,
    "memory": 4096,
    "storage": 50
  }
}
Response:
{
  "id": "db_xxx",
  "name": "production",
  "railway_service_id": "srv_xxx",
  "region": "us-west1",
  "status": "provisioning",
  "created_at": "2026-01-20T10:00:00Z"
}

Get Database

GET /projects/:project_id/databases/:name
Authorization: Bearer <token>

Get Connection URL

GET /projects/:project_id/databases/:name/url
Authorization: Bearer <token>
Response:
{
  "host": "xxx.proxy.rlwy.net",
  "port": 12345,
  "database": "railway",
  "user": "postgres",
  "connection_string": "postgresql://postgres:xxx@xxx.proxy.rlwy.net:12345/railway?sslmode=disable"
}

Delete Database

DELETE /projects/:project_id/databases/:name
Authorization: Bearer <token>

Backups

List Backups

GET /projects/:project_id/databases/:name/backups
Authorization: Bearer <token>
Response:
{
  "backups": [
    {
      "id": "bkp_xxx",
      "type": "automated",
      "status": "completed",
      "size_bytes": 12345678,
      "created_at": "2026-01-25T03:00:00Z",
      "expires_at": "2026-01-28T03:00:00Z"
    }
  ]
}

Create Backup

POST /projects/:project_id/databases/:name/backups
Authorization: Bearer <token>
Response:
{
  "id": "bkp_xxx",
  "type": "manual",
  "status": "pending",
  "created_at": "2026-01-25T14:30:00Z"
}

Get Backup Details

GET /projects/:project_id/databases/:name/backups/:backup_id
Authorization: Bearer <token>

Download Backup

GET /projects/:project_id/databases/:name/backups/:backup_id/download
Authorization: Bearer <token>

Returns a pre-signed URL for downloading the backup file.

Response:
{
  "download_url": "https://...",
  "expires_at": "2026-01-25T15:30:00Z"
}

Restore from Backup

POST /projects/:project_id/databases/:name/backups/:backup_id/restore
Authorization: Bearer <token>
Response:
{
  "restore_id": "rstr_xxx",
  "status": "pending",
  "started_at": "2026-01-25T14:30:00Z"
}

Delete Backup

DELETE /projects/:project_id/databases/:name/backups/:backup_id
Authorization: Bearer <token>

PITR (Point-in-Time Recovery)

Get PITR Config

GET /projects/:project_id/databases/:name/pitr/config
Authorization: Bearer <token>
Response:
{
  "enabled": true,
  "base_backup_id": "bkp_xxx",
  "retention_days": 7,
  "recovery_window": {
    "from": "2026-01-18T03:00:00Z",
    "to": "2026-01-25T14:45:00Z"
  }
}

Enable PITR

POST /projects/:project_id/databases/:name/pitr/enable
Authorization: Bearer <token>
Content-Type: application/json
 
{
  "retention_days": 7
}
Response:
{
  "enabled": true,
  "base_backup_id": "bkp_xxx",
  "wal_receiver_status": "starting"
}

Disable PITR

POST /projects/:project_id/databases/:name/pitr/disable
Authorization: Bearer <token>

List WAL Archives

GET /projects/:project_id/databases/:name/pitr/wal
Authorization: Bearer <token>
Response:
{
  "archives": [
    {
      "filename": "000000010000000000000042",
      "size_bytes": 16777216,
      "archived_at": "2026-01-25T14:44:45Z"
    }
  ],
  "total_count": 42,
  "total_size_bytes": 704643072
}

Get Recovery Window

GET /projects/:project_id/databases/:name/pitr/recovery-window
Authorization: Bearer <token>
Response:
{
  "from": "2026-01-18T03:00:00Z",
  "to": "2026-01-25T14:45:00Z",
  "base_backup_time": "2026-01-18T03:00:00Z",
  "latest_wal_time": "2026-01-25T14:45:00Z"
}

Initiate PITR Restore

POST /projects/:project_id/databases/:name/pitr/restore
Authorization: Bearer <token>
Content-Type: application/json
 
{
  "target_time": "2026-01-25T14:30:00Z"
}

Or for latest recovery:

{
  "target_time": "latest"
}
Response:
{
  "restore_id": "rstr_xxx",
  "target_time": "2026-01-25T14:30:00Z",
  "status": "pending",
  "started_at": "2026-01-25T14:50:00Z"
}

List PITR Restores

GET /projects/:project_id/databases/:name/pitr/restores
Authorization: Bearer <token>
Response:
{
  "restores": [
    {
      "id": "rstr_xxx",
      "target_time": "2026-01-25T14:30:00Z",
      "status": "completed",
      "wal_files_applied": 35,
      "started_at": "2026-01-25T14:50:00Z",
      "completed_at": "2026-01-25T14:55:00Z"
    }
  ]
}

Get Restore Status

GET /projects/:project_id/databases/:name/pitr/restores/:restore_id
Authorization: Bearer <token>

Get WAL Receiver Status

GET /projects/:project_id/databases/:name/pitr/receiver-status
Authorization: Bearer <token>
Response:
{
  "status": "running",
  "started_at": "2026-01-24T03:05:00Z",
  "last_wal_file": "000000010000000000000042",
  "bytes_received": 704643072,
  "errors": 0,
  "lag_seconds": 15
}

Restart WAL Receiver

POST /projects/:project_id/databases/:name/pitr/restart-receiver
Authorization: Bearer <token>

Error Codes

CodeDescription
AUTH_REQUIREDMissing or invalid authorization
PROJECT_NOT_FOUNDProject does not exist
DATABASE_NOT_FOUNDDatabase does not exist
BACKUP_NOT_FOUNDBackup does not exist
PITR_NOT_ENABLEDPITR is not enabled for this database
TARGET_TIME_INVALIDTarget time is outside recovery window
RATE_LIMIT_EXCEEDEDToo many requests
INTERNAL_ERRORServer error