API Reference

Complete REST API documentation for managing projects, credentials, connectors, and proxies.

Base URL

All API endpoints are prefixed with /api/v1. For example:

http://localhost:8000/api/v1/projects

Authentication

All API endpoints except /api/v1/auth/* and /health require a valid JWT token. Mutation endpoints require at least Editor role; user management requires Admin role.

Login

POST /api/v1/auth/login
Content-Type: application/json

{
  "username": "admin",
  "password": "your-password"
}

Response:

{
  "access_token": "eyJhbGciOiJIUzI1NiIs...",
  "token_type": "bearer",
  "expires_in": 86400
}

Using the Token

Include the token in the Authorization header:

curl -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
  http://localhost:8000/api/v1/projects

Check Auth Status

GET /api/v1/auth/status

Projects

Projects provide multi-tenancy support. Each project has its own credentials, connectors, and proxy pools.

List Projects

GET /api/v1/projects

Create Project

POST /api/v1/projects
Content-Type: application/json

{
  "name": "My Project",
  "description": "Production proxy pool",
  "username": "proxy-user",
  "password": "proxy-password",
  "routing_strategy": "round_robin"
}

Get Project

GET /api/v1/projects/{project_id}

Update Project

PATCH /api/v1/projects/{project_id}
Content-Type: application/json

{
  "name": "Updated Name",
  "routing_strategy": "least_used"
}

Delete Project

DELETE /api/v1/projects/{project_id}

Credentials

Credentials store cloud provider authentication details.

List Credentials

GET /api/v1/projects/{project_id}/credentials

Create Credential

POST /api/v1/projects/{project_id}/credentials
Content-Type: application/json

{
  "name": "AWS Production",
  "type": "aws",
  "config": {
    "access_key": "AKIAIOSFODNN7EXAMPLE",
    "secret_key": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
  }
}

Credential Types: aws, gcp, azure, static

Get Credential

GET /api/v1/projects/{project_id}/credentials/{credential_id}

Update Credential

PATCH /api/v1/projects/{project_id}/credentials/{credential_id}

Delete Credential

DELETE /api/v1/projects/{project_id}/credentials/{credential_id}

Connectors

Connectors define how proxies are provisioned (cloud instances or static).

List Connectors

GET /api/v1/projects/{project_id}/connectors

Create Connector

POST /api/v1/projects/{project_id}/connectors
Content-Type: application/json

{
  "name": "AWS US-East Proxies",
  "credential_id": "credential-uuid",
  "config": {
    "instance_name": "octoprox-proxy",
    "region": "us-east-1",
    "instance_type": "t3.micro",
    "security_group": "sg-0123456789abcdef0",
    "min_proxies": 1,
    "max_proxies": 10
  },
  "routing_config": {
    "domain_whitelist": ["example.com", "api.example.com"]
  },
  "rate_limit_config": {
    "max_requests": 100,
    "window_seconds": 60,
    "quarantine_seconds_min": 120,
    "quarantine_seconds_max": 300
  }
}

Domain Filtering (routing_config)

Connectors support optional domain-based filtering to control which target domains their proxies serve. The routing_config field accepts:

  • domain_whitelist — Only route requests for these domains through this connector’s proxies.
  • domain_blacklist — Route all requests except these domains through this connector’s proxies.

Whitelist and blacklist are mutually exclusive — you can set one or the other, but not both.

Domain matching is hierarchical: entering bing.com matches bing.com and all subdomains (www.bing.com, images.bing.com, etc.).

Examples:

Whitelist — only allow specific domains:

{
  "routing_config": {
    "domain_whitelist": ["example.com", "api.example.com"]
  }
}

Blacklist — block specific domains:

{
  "routing_config": {
    "domain_blacklist": ["blocked.com", "ads.tracker.net"]
  }
}

No restrictions (default):

{
  "routing_config": {}
}

Rate Limiting (rate_limit_config)

Connectors support optional per-proxy rate limiting. When a proxy exceeds max_requests within window_seconds, it is quarantined (excluded from selection) for a random duration between quarantine_seconds_min and quarantine_seconds_max. See the Rate Limiting guide for details.

Field Type Description
max_requests integer Max requests per proxy in the window
window_seconds integer Sliding window duration (1–86400)
quarantine_seconds_min integer Min quarantine duration (1–86400)
quarantine_seconds_max integer Max quarantine duration (1–86400)
sticky_quarantine boolean Block sticky session fallback (default: false)

Example:

{
  "rate_limit_config": {
    "max_requests": 100,
    "window_seconds": 60,
    "quarantine_seconds_min": 120,
    "quarantine_seconds_max": 300,
    "sticky_quarantine": false
  }
}

Disabled (default):

{
  "rate_limit_config": {}
}

Unquarantine Proxy

Forcefully remove a proxy from quarantine:

POST /api/v1/projects/{project_id}/proxies/{proxy_id}/unquarantine

Returns 200 with {"status": "ok", "proxy_id": "..."} on success, 400 if the proxy is not quarantined.

Get Connector Options

Get available regions, instance types, and other options for each cloud provider:

GET /api/v1/connector-options

Get Connector

GET /api/v1/projects/{project_id}/connectors/{connector_id}

Update Connector

PATCH /api/v1/projects/{project_id}/connectors/{connector_id}
Content-Type: application/json

{
  "name": "Updated Name",
  "routing_config": {
    "domain_whitelist": ["new-domain.com"]
  }
}

Delete Connector

DELETE /api/v1/projects/{project_id}/connectors/{connector_id}

Proxies

Proxies are the actual proxy servers managed by Octoprox.

List Proxies

GET /api/v1/projects/{project_id}/proxies

Create Proxy (Static)

POST /api/v1/projects/{project_id}/proxies
Content-Type: application/json

{
  "connector_id": "connector-uuid",
  "host": "192.168.1.100",
  "port": 3128,
  "protocol": "http",
  "username": "proxy-user",
  "password": "proxy-pass"
}

Protocols: http, https, socks4, socks5

Upload Proxies (Bulk)

Upload multiple proxies from a CSV file:

POST /api/v1/projects/{project_id}/proxies/upload
Content-Type: multipart/form-data

file: proxies.csv
connector_id: connector-uuid

CSV format (one proxy per line):

http://192.168.1.1:8080
socks5://user:pass@10.0.0.1:1080

Get Proxy

GET /api/v1/projects/{project_id}/proxies/{proxy_id}

Delete Proxy

DELETE /api/v1/projects/{project_id}/proxies/{proxy_id}

Metrics

Get Project Metrics

GET /api/v1/projects/{project_id}/metrics

Response:

{
  "total_proxies": 10,
  "healthy_proxies": 8,
  "total_requests": 15420,
  "success_rate": 0.98,
  "avg_latency_ms": 145.2
}

Prometheus Metrics

Export metrics in Prometheus format:

GET /api/v1/projects/{project_id}/metrics/prometheus

Backup & Migration

Admin-only endpoints for exporting the entire Octoprox setup to a single encrypted file and restoring it on the same or another instance. Useful for disaster recovery and for migrating between deployments.

Export Backup

POST /api/v1/backup/export

Request:

{
  "passphrase": "correct horse battery staple",
  "include_metrics": false
}
Field Type Notes
passphrase string Minimum 8 characters. Required again to import — it cannot be recovered.
include_metrics boolean Include historical proxy/project metrics. Default false (smaller file).

Response: the backup file as application/octet-stream with a Content-Disposition: attachment; filename="octoprox-backup-YYYY-MM-DD.opbak" header.

The file covers users (including password hashes), projects, credentials, connectors, proxies and, optionally, metrics.

Import Backup

POST /api/v1/backup/import
Content-Type: multipart/form-data
Form field Type Notes
file file The .opbak file produced by export.
passphrase string The passphrase used when exporting.
mode string Only replace is supported (default).
keep_current_user boolean Default false. See below.

Import replaces all existing data on the instance. The wipe and restore run in a single transaction, so a failure leaves the existing data untouched. Afterwards the live proxy cache is rebuilt and stale Redis state for the replaced projects and proxies is purged.

With keep_current_user=true the calling admin’s own account survives the wipe, so an admin importing a backup taken from another instance is not locked out. Imported users that would collide with the kept account are adjusted:

  • same id → the imported user receives a fresh id
  • same username → the imported user is renamed to <username>-imported (then -imported-2, -imported-3, … if needed)
  • same non-empty email → the imported user’s email is cleared

With keep_current_user=false (the default) users are restored exactly as they are in the backup; the current session’s user may no longer exist, so log in again with credentials that are valid in the backup.

Response:

{
  "users": 3,
  "projects": 2,
  "credentials": 1,
  "connectors": 2,
  "proxies": 14,
  "proxy_metrics": 0,
  "project_metrics": 0,
  "kept_current_user": true,
  "user_conflicts": [
    {
      "original_username": "admin",
      "new_username": "admin-imported",
      "new_id": true,
      "email_cleared": false
    }
  ]
}

users counts imported rows only; the kept account is not included.

Errors (HTTP 400):

  • Incorrect passphrase or corrupt file.
  • File is not an Octoprox backup.
  • Backup was created by a newer Octoprox (format_version too high).
  • Schema mismatch: the backup’s Alembic revision differs from this instance’s. Upgrade both instances to the same Octoprox version, then retry. This check runs before decryption, so it does not require the passphrase.
  • keep_current_user=true but the caller’s account has no database row.

Backup File Format

An .opbak file is a small JSON envelope. The metadata is plain text so an importer can check compatibility before asking for the passphrase; the data is encrypted:

{
  "format": "octoprox-backup",
  "format_version": 1,
  "created_at": "2026-09-04T10:15:00+00:00",
  "app_version": "1.0.1",
  "schema_version": "<alembic revision>",
  "includes_metrics": false,
  "kdf": { "algo": "pbkdf2-sha256", "iterations": 600000, "salt": "<base64>" },
  "ciphertext": "<base64 Fernet token>"
}

The ciphertext is gzipped JSON encrypted with Fernet (AES-128-CBC + HMAC-SHA256). The key is derived from the passphrase with PBKDF2-HMAC-SHA256 and a random per-file salt. Treat the file as sensitive: it contains password hashes and provider credentials, protected only by the passphrase.


Health Check

Public endpoint for load balancer health checks:

GET /health

Response:

{
  "status": "healthy"
}