Polykomos API Reference

Provision and manage PostgreSQL and MySQL databases programmatically.

Quick Start

Validate your key, then create your first database in two requests.

Base URLhttps://polykomos.com
AuthAuthorization: Bearer pk_live_...
FormatAll responses are JSON. All request bodies are JSON.
Team targetingPass team_id when creating a database to target a specific team (or use your primary team by default).
TracingEvery response includes request_id in the body and X-Request-Id header.
# Verify your API key curl -sS https://polykomos.com/api/v1/me \ -H "Authorization: Bearer $POLYKOMOS_API_KEY" # Create a database curl -sS -X POST "https://polykomos.com/api/v1/databases?wait=true&timeout=30" \ -H "Authorization: Bearer $POLYKOMOS_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"name": "my-app-db", "region": "us-east-1"}'
import requests api_key = "pk_live_..." headers = {"Authorization": f"Bearer {api_key}"} # Verify your API key me = requests.get("https://polykomos.com/api/v1/me", headers=headers) print(me.json()) # Create a database import uuid resp = requests.post( "https://polykomos.com/api/v1/databases", headers={**headers, "Idempotency-Key": str(uuid.uuid4())}, params={"wait": "true", "timeout": 30}, json={"name": "my-app-db", "region": "us-east-1"}, ) print(resp.json())
const API_KEY = "pk_live_..."; const headers = { "Authorization": `Bearer ${API_KEY}`, "Content-Type": "application/json", }; // Verify your API key const me = await fetch("https://polykomos.com/api/v1/me", { headers }); console.log(await me.json()); // Create a database const resp = await fetch( "https://polykomos.com/api/v1/databases?wait=true&timeout=30", { method: "POST", headers: { ...headers, "Idempotency-Key": crypto.randomUUID() }, body: JSON.stringify({ name: "my-app-db", region: "us-east-1" }), } ); console.log(await resp.json());
$apiKey = "pk_live_..."; $headers = ["Authorization: Bearer $apiKey", "Content-Type: application/json"]; // Verify your API key $ch = curl_init("https://polykomos.com/api/v1/me"); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $me = json_decode(curl_exec($ch), true); print_r($me); // Create a database $ch = curl_init("https://polykomos.com/api/v1/databases?wait=true&timeout=30"); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_HTTPHEADER, array_merge($headers, [ "Idempotency-Key: " . bin2hex(random_bytes(16)), ])); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([ "name" => "my-app-db", "region" => "us-east-1", ])); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $db = json_decode(curl_exec($ch), true); print_r($db);
require "net/http" require "json" require "securerandom" api_key = "pk_live_..." uri = URI("https://polykomos.com/api/v1/me") req = Net::HTTP::Get.new(uri) req["Authorization"] = "Bearer #{api_key}" res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) } puts JSON.parse(res.body) # Create a database uri = URI("https://polykomos.com/api/v1/databases?wait=true&timeout=30") req = Net::HTTP::Post.new(uri) req["Authorization"] = "Bearer #{api_key}" req["Content-Type"] = "application/json" req["Idempotency-Key"] = SecureRandom.uuid req.body = { name: "my-app-db", region: "us-east-1" }.to_json res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) } puts JSON.parse(res.body)
package main import ( "bytes" "encoding/json" "fmt" "net/http" "github.com/google/uuid" ) func main() { apiKey := "pk_live_..." // Verify your API key req, _ := http.NewRequest("GET", "https://polykomos.com/api/v1/me", nil) req.Header.Set("Authorization", "Bearer "+apiKey) resp, _ := http.DefaultClient.Do(req) defer resp.Body.Close() // Create a database body, _ := json.Marshal(map[string]string{ "name": "my-app-db", "region": "us-east-1", }) req, _ = http.NewRequest("POST", "https://polykomos.com/api/v1/databases?wait=true&timeout=30", bytes.NewReader(body)) req.Header.Set("Authorization", "Bearer "+apiKey) req.Header.Set("Content-Type", "application/json") req.Header.Set("Idempotency-Key", uuid.New().String()) resp, _ = http.DefaultClient.Do(req) fmt.Println(resp.Status) }

Natural Language Queries

Use POST /api/v1/query_executions to ask questions in plain English and execute the generated SQL safely on one of your databases.

RequirementDetails
queries:write scopeYour API key must include query execution permissions.
Active databaseThe target database_uuid must be in active status.
Supported enginesPostgreSQL and MySQL are supported.
Required fieldsSend database_uuid and query in JSON.
curl -sS -X POST "https://polykomos.com/api/v1/query_executions" \ -H "Authorization: Bearer $POLYKOMOS_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "database_uuid": "d7f3a1b2-4c5e-6f7a-8b9c-0d1e2f3a4b5c", "query": "show all contacts created this month" }'

The response includes the generated SQL, execution result, and a query tracking ID for auditing.

Authentication

Every request must include an API key in the Authorization header.

API keys use the prefix pk_live_ and are created from the API Keys dashboard. The raw key is shown once at creation time. We store only a SHA-256 hash.

Authorization: Bearer pk_live_a1b2c3d4e5f6...

Scopes control what each key can do:

ScopeGrants access to
databases:readList databases, get a database, read catalog.
databases:writeCreate, update, and delete databases.
databases:*All database operations.
webhooks:readList webhook endpoints and deliveries.
webhooks:writeCreate, revoke, and test webhook endpoints.
blueprints:readList blueprints, get a blueprint, validate SQL, view applications.
blueprints:writeCreate, update, and delete blueprints.
queries:writeExecute natural language queries against databases.

Keys can also have per-key controls: IP allowlists, requests-per-minute limits, monthly quotas, and inactivity TTLs. Configure these in the dashboard.

Versioning

The API is versioned via the URL path: /api/v1/. When breaking changes are needed, a new version (/api/v2/) will be introduced. The previous version will continue to work for at least 12 months after deprecation is announced.

Non-breaking changes (new fields in responses, new optional parameters, new endpoints) are added to the current version without a version bump.

Rate Limits

Requests are limited per API key.

LimitDefaultNotes
Requests per minute120Configurable per key in the dashboard.
Monthly quotaUnlimitedOptional hard cap. Set in key controls.

When rate limited, the response includes a Retry-After: 60 header. Back off and retry.

429 Response
{ "error": { "code": "rate_limit_exceeded", "message": "Rate limit exceeded for this API key.", "details": {} }, "request_id": "req_a1b2c3d4e5f6" }

Pagination

List endpoints return paginated results.

ParameterTypeDefaultDescription
limitinteger25Number of items to return. Max 100.
starting_afterstring-Cursor: the UUID (or ID) of the last item from the previous page.

Responses include a has_more boolean. When true, pass the last item's identifier as starting_after to fetch the next page.

# First page curl -sS "https://polykomos.com/api/v1/databases?limit=10" \ -H "Authorization: Bearer $POLYKOMOS_API_KEY" # Next page (use the uuid of the last item) curl -sS "https://polykomos.com/api/v1/databases?limit=10&starting_after=d7f3a1b2-..." \ -H "Authorization: Bearer $POLYKOMOS_API_KEY"

Idempotency

Only specific mutating endpoints require an Idempotency-Key header.

Generate a unique value (a UUID works well) for each distinct operation. If you retry a failed request with the same key and payload, you'll get the original response back instead of creating a duplicate.

  • POST /api/v1/databases
  • PATCH /api/v1/databases/:uuid
  • PATCH /api/v1/databases/:uuid/quotas
  • DELETE /api/v1/databases/:uuid
  • POST /api/v1/databases/:uuid/blueprint_applications
  • POST /api/v1/webhook_endpoints
  • DELETE /api/v1/webhook_endpoints/:id
  • POST /api/v1/blueprints
ScenarioBehavior
Same key + same payloadReturns the cached response (marked idempotency_replay: true).
Same key + different payload409 Conflict with code idempotency_key_conflict.
Key still in-flight409 Conflict with code idempotency_key_in_progress.

Keys expire after 24 hours.

# Bash export IDEMPOTENCY_KEY="$(uuidgen)" # JavaScript const idempotencyKey = crypto.randomUUID(); # Python import uuid idempotency_key = str(uuid.uuid4())

Errors

All errors follow a consistent envelope.

{ "error": { "code": "missing_required_field", "message": "Missing required field: name", "details": { "field": "name" } }, "request_id": "req_a1b2c3d4e5f6" }
StatusMeaningWhat to do
400Bad request (malformed JSON).Fix the request body.
401Missing or malformed Authorization header.Check your API key.
403Invalid key, expired key, IP blocked, or missing scope.Check key status, scopes, and controls.
404Resource not found.Verify the UUID or ID belongs to your account.
405HTTP method not allowed on this endpoint.Check the docs for allowed methods.
409Idempotency conflict.Use the same payload or generate a new key.
422Validation error (missing field, invalid value).Check details for the specific field.
429Rate limit or quota exceeded.Back off. Check Retry-After header.
500Internal server error.Retry with the same Idempotency-Key. Contact support if persistent.

GET /api/v1/me

Returns the authenticated user and API key context. Use this to verify your key is valid.

Scope: Any valid key (no specific scope required).

curl -sS https://polykomos.com/api/v1/me \ -H "Authorization: Bearer $POLYKOMOS_API_KEY"
import requests resp = requests.get( "https://polykomos.com/api/v1/me", headers={"Authorization": f"Bearer {api_key}"}, ) print(resp.json())
const resp = await fetch("https://polykomos.com/api/v1/me", { headers: { Authorization: `Bearer ${API_KEY}` }, }); console.log(await resp.json());
$ch = curl_init("https://polykomos.com/api/v1/me"); curl_setopt($ch, CURLOPT_HTTPHEADER, ["Authorization: Bearer $apiKey"]); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $result = json_decode(curl_exec($ch), true);
require "net/http" require "json" uri = URI("https://polykomos.com/api/v1/me") req = Net::HTTP::Get.new(uri) req["Authorization"] = "Bearer #{api_key}" res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) } puts JSON.parse(res.body)
package main import ( "fmt" "io" "net/http" ) func main() { req, _ := http.NewRequest("GET", "https://polykomos.com/api/v1/me", nil) req.Header.Set("Authorization", "Bearer "+apiKey) resp, _ := http.DefaultClient.Do(req) defer resp.Body.Close() body, _ := io.ReadAll(resp.Body) fmt.Println(string(body)) }
200 Response
{ "data": { "user": { "object": "user", "name": "Jane Smith", "email": "jane@example.com" }, "api_key": { "object": "api_key", "name": "Production Key", "preview": "pk_live_••••••••a1b2", "permissions": ["databases:read", "databases:write"], "status": "active", "last_used_at": "2026-02-10 14:23:01", "controls": { "requests_per_minute": 120, "monthly_quota": null, "allowed_ip_list": [], "inactive_ttl_days": null } } }, "request_id": "req_a1b2c3d4e5f6a1b2c3d4" }
GET /api/v1/database_types

Returns available database engines and regions. Use this before creating a database to get valid db_type and region values.

Scope: databases:read

curl -sS https://polykomos.com/api/v1/database_types \ -H "Authorization: Bearer $POLYKOMOS_API_KEY"
import requests resp = requests.get( "https://polykomos.com/api/v1/database_types", headers={"Authorization": f"Bearer {api_key}"}, ) print(resp.json())
const resp = await fetch("https://polykomos.com/api/v1/database_types", { headers: { Authorization: `Bearer ${API_KEY}` }, }); console.log(await resp.json());
$ch = curl_init("https://polykomos.com/api/v1/database_types"); curl_setopt($ch, CURLOPT_HTTPHEADER, ["Authorization: Bearer $apiKey"]); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $result = json_decode(curl_exec($ch), true); print_r($result);
require "net/http" require "json" uri = URI("https://polykomos.com/api/v1/database_types") req = Net::HTTP::Get.new(uri) req["Authorization"] = "Bearer #{api_key}" res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) } puts JSON.parse(res.body)
package main import ( "fmt" "io" "net/http" ) func main() { req, _ := http.NewRequest("GET", "https://polykomos.com/api/v1/database_types", nil) req.Header.Set("Authorization", "Bearer "+apiKey) resp, _ := http.DefaultClient.Do(req) defer resp.Body.Close() body, _ := io.ReadAll(resp.Body) fmt.Println(string(body)) }
200 Response
{ "data": [ { "value": "postgres", "label": "PostgreSQL", "is_provisionable": true, "is_available": true, "regions": [ { "code": "us-east-1", "label": "US East (Virginia)", "is_available": true }, { "code": "eu-west-1", "label": "EU West (Ireland)", "is_available": true } ] } ], "request_id": "req_a1b2c3d4e5f6a1b2c3d4" }
GET /api/v1/databases

Returns a paginated list of databases you have access to.

Scope: databases:read

ParameterTypeDescription
limitintegerItems per page (1-100, default 25).
starting_afterstringUUID of the last database from the previous page.
curl -sS "https://polykomos.com/api/v1/databases?limit=10" \ -H "Authorization: Bearer $POLYKOMOS_API_KEY"
import requests resp = requests.get( "https://polykomos.com/api/v1/databases", headers={"Authorization": f"Bearer {api_key}"}, params={"limit": 10}, ) databases = resp.json()["data"]
const resp = await fetch("https://polykomos.com/api/v1/databases?limit=10", { headers: { Authorization: `Bearer ${API_KEY}` }, }); const { data, has_more } = await resp.json();
$ch = curl_init("https://polykomos.com/api/v1/databases?limit=10"); curl_setopt($ch, CURLOPT_HTTPHEADER, ["Authorization: Bearer $apiKey"]); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $result = json_decode(curl_exec($ch), true); $databases = $result["data"];
require "net/http" require "json" uri = URI("https://polykomos.com/api/v1/databases?limit=10") req = Net::HTTP::Get.new(uri) req["Authorization"] = "Bearer #{api_key}" res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) } databases = JSON.parse(res.body)["data"]
package main import ( "encoding/json" "fmt" "io" "net/http" ) func main() { req, _ := http.NewRequest("GET", "https://polykomos.com/api/v1/databases?limit=10", nil) req.Header.Set("Authorization", "Bearer "+apiKey) resp, _ := http.DefaultClient.Do(req) defer resp.Body.Close() body, _ := io.ReadAll(resp.Body) var result map[string]interface{} json.Unmarshal(body, &result) databases := result["data"] fmt.Println(databases) }
200 Response
{ "data": [ { "object": "database", "uuid": "d7f3a1b2-4c5e-6f7a-8b9c-0d1e2f3a4b5c", "name": "my-app-db", "status": "active", "region": "us-east-1", "plan": "free", "quotas": { "storage_hard_limit_gb": 10, "connection_hard_limit": 50, "warning_threshold_pct": 80 }, "db_type": "postgres", "host": "db-42.polykomos.com", "port": 5432, "db_name": "my-app-db", "db_username": "u42", "team_id": 12, "team_name": "Acme Data Team", "connection_string": "postgresql://u42:***@db-42.polykomos.com:5432/my-app-db", "created_at": "2026-02-10T12:00:00Z", "updated_at": "2026-02-10T12:01:30Z" } ], "has_more": false, "request_id": "req_a1b2c3d4e5f6a1b2c3d4" }
POST /api/v1/databases

Creates a new database. If a pre-provisioned database is available in the pool, it's assigned instantly. Otherwise, provisioning happens asynchronously.

Pass team_id to create in a specific team. If omitted, your primary team is used.

Scope: databases:write   Idempotency: Required

ParameterLocationTypeDescription
name requiredbodystringLowercase letters, numbers, and hyphens. 1-63 chars.
db_typebodystringDatabase engine. Default: postgres.
regionbodystringRegion code from the catalog. Auto-selected if omitted.
planbodystringfree or pro. Default: free.
team_idbodyintegerOptional target team ID for the new database.
storage_hard_limit_gbbodynumberOptional storage hard cap override (GB). Omit for plan default.
connection_hard_limitbodyintegerOptional connection hard cap override. Omit for plan default.
warning_threshold_pctbodyintegerOptional warning threshold (1-100). Omit for plan default.
waitquerybooleanIf true, block until provisioning completes or timeout.
timeoutqueryintegerMax seconds to wait (1-120, default 30). Only used when wait=true.
curl -sS -X POST "https://polykomos.com/api/v1/databases?wait=true&timeout=30" \ -H "Authorization: Bearer $POLYKOMOS_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{ "name": "orders-prod-db", "db_type": "postgres", "region": "us-east-1", "plan": "free", "storage_hard_limit_gb": 10, "connection_hard_limit": 50, "warning_threshold_pct": 80 }'
import uuid import requests resp = requests.post( "https://polykomos.com/api/v1/databases", headers={ "Authorization": f"Bearer {api_key}", "Idempotency-Key": str(uuid.uuid4()), }, params={"wait": "true", "timeout": 30}, json={ "name": "orders-prod-db", "db_type": "postgres", "region": "us-east-1", "plan": "free", "storage_hard_limit_gb": 10, "connection_hard_limit": 50, "warning_threshold_pct": 80, }, ) db = resp.json()["data"] print(f"Connection: {db['connection_string']}")
const resp = await fetch( "https://polykomos.com/api/v1/databases?wait=true&timeout=30", { method: "POST", headers: { Authorization: `Bearer ${API_KEY}`, "Content-Type": "application/json", "Idempotency-Key": crypto.randomUUID(), }, body: JSON.stringify({ name: "orders-prod-db", db_type: "postgres", region: "us-east-1", plan: "free", storage_hard_limit_gb: 10, connection_hard_limit: 50, warning_threshold_pct: 80, }), } ); const { data } = await resp.json(); console.log(data.connection_string);
$ch = curl_init("https://polykomos.com/api/v1/databases?wait=true&timeout=30"); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_HTTPHEADER, [ "Authorization: Bearer $apiKey", "Content-Type: application/json", "Idempotency-Key: " . bin2hex(random_bytes(16)), ]); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([ "name" => "orders-prod-db", "db_type" => "postgres", "region" => "us-east-1", "plan" => "free", "storage_hard_limit_gb" => 10, "connection_hard_limit" => 50, "warning_threshold_pct" => 80, ])); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $result = json_decode(curl_exec($ch), true); echo $result["data"]["connection_string"];
require "net/http" require "json" require "securerandom" uri = URI("https://polykomos.com/api/v1/databases?wait=true&timeout=30") req = Net::HTTP::Post.new(uri) req["Authorization"] = "Bearer #{api_key}" req["Content-Type"] = "application/json" req["Idempotency-Key"] = SecureRandom.uuid req.body = { name: "orders-prod-db", db_type: "postgres", region: "us-east-1", plan: "free", storage_hard_limit_gb: 10, connection_hard_limit: 50, warning_threshold_pct: 80 }.to_json res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) } db = JSON.parse(res.body)["data"] puts db["connection_string"]
package main import ( "bytes" "encoding/json" "fmt" "io" "net/http" "github.com/google/uuid" ) func main() { body, _ := json.Marshal(map[string]string{ "name": "orders-prod-db", "db_type": "postgres", "region": "us-east-1", "plan": "free", "storage_hard_limit_gb": 10, "connection_hard_limit": 50, "warning_threshold_pct": 80, }) req, _ := http.NewRequest("POST", "https://polykomos.com/api/v1/databases?wait=true&timeout=30", bytes.NewReader(body)) req.Header.Set("Authorization", "Bearer "+apiKey) req.Header.Set("Content-Type", "application/json") req.Header.Set("Idempotency-Key", uuid.New().String()) resp, _ := http.DefaultClient.Do(req) defer resp.Body.Close() respBody, _ := io.ReadAll(resp.Body) var result map[string]interface{} json.Unmarshal(respBody, &result) db := result["data"].(map[string]interface{}) fmt.Println(db["connection_string"]) }
201 Response (Provisioned)
{ "message": "Database provisioned.", "data": { "object": "database", "uuid": "d7f3a1b2-4c5e-6f7a-8b9c-0d1e2f3a4b5c", "name": "orders-prod-db", "status": "active", "region": "us-east-1", "plan": "free", "quotas": { "storage_hard_limit_gb": 10, "connection_hard_limit": 50, "warning_threshold_pct": 80 }, "db_type": "postgres", "host": "db-42.polykomos.com", "port": 5432, "db_name": "orders-prod-db", "db_username": "u42", "db_password": "a1b2c3d4e5f6g7h8i9j0", "team_id": 12, "team_name": "Acme Data Team", "connection_string": "postgresql://u42:a1b2c3d4e5f6g7h8i9j0@db-42.polykomos.com:5432/orders-prod-db", "created_at": "2026-02-10T12:00:00Z", "updated_at": "2026-02-10T12:01:30Z" }, "request_id": "req_a1b2c3d4e5f6a1b2c3d4" }
202 Response (Still Provisioning)
{ "message": "Database is still provisioning.", "data": { "object": "database", "uuid": "d7f3...", "status": "provisioning", ... }, "provisioning": { "completed": false, "waited_seconds": 30, "poll_url": "/api/v1/databases/d7f3a1b2-4c5e-6f7a-8b9c-0d1e2f3a4b5c" }, "request_id": "req_..." }
GET /api/v1/databases/:uuid

Returns a single database by UUID. Includes connection credentials.

Scope: databases:read

curl -sS "https://polykomos.com/api/v1/databases/d7f3a1b2-4c5e-6f7a-8b9c-0d1e2f3a4b5c" \ -H "Authorization: Bearer $POLYKOMOS_API_KEY"
import requests db_uuid = "d7f3a1b2-4c5e-6f7a-8b9c-0d1e2f3a4b5c" resp = requests.get( f"https://polykomos.com/api/v1/databases/{db_uuid}", headers={"Authorization": f"Bearer {api_key}"}, ) db = resp.json()["data"]
const dbUuid = "d7f3a1b2-4c5e-6f7a-8b9c-0d1e2f3a4b5c"; const resp = await fetch( `https://polykomos.com/api/v1/databases/${dbUuid}`, { headers: { Authorization: `Bearer ${API_KEY}` } } ); const { data } = await resp.json();
$dbUuid = "d7f3a1b2-4c5e-6f7a-8b9c-0d1e2f3a4b5c"; $ch = curl_init("https://polykomos.com/api/v1/databases/$dbUuid"); curl_setopt($ch, CURLOPT_HTTPHEADER, ["Authorization: Bearer $apiKey"]); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $result = json_decode(curl_exec($ch), true); $db = $result["data"];
require "net/http" require "json" db_uuid = "d7f3a1b2-4c5e-6f7a-8b9c-0d1e2f3a4b5c" uri = URI("https://polykomos.com/api/v1/databases/#{db_uuid}") req = Net::HTTP::Get.new(uri) req["Authorization"] = "Bearer #{api_key}" res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) } db = JSON.parse(res.body)["data"]
package main import ( "encoding/json" "fmt" "io" "net/http" ) func main() { dbUuid := "d7f3a1b2-4c5e-6f7a-8b9c-0d1e2f3a4b5c" req, _ := http.NewRequest("GET", "https://polykomos.com/api/v1/databases/"+dbUuid, nil) req.Header.Set("Authorization", "Bearer "+apiKey) resp, _ := http.DefaultClient.Do(req) defer resp.Body.Close() body, _ := io.ReadAll(resp.Body) var result map[string]interface{} json.Unmarshal(body, &result) db := result["data"] fmt.Println(db) }
200 Response
{ "data": { "object": "database", "uuid": "d7f3a1b2-4c5e-6f7a-8b9c-0d1e2f3a4b5c", "name": "orders-prod-db", "status": "active", "region": "us-east-1", "plan": "free", "quotas": { "storage_hard_limit_gb": 10, "connection_hard_limit": 50, "warning_threshold_pct": 80 }, "db_type": "postgres", "host": "db-42.polykomos.com", "port": 5432, "db_name": "orders-prod-db", "db_username": "u42", "db_password": "a1b2c3d4e5f6g7h8i9j0", "team_id": 12, "team_name": "Acme Data Team", "connection_string": "postgresql://u42:a1b2c3d4e5f6g7h8i9j0@db-42.polykomos.com:5432/orders-prod-db", "created_at": "2026-02-10T12:00:00Z", "updated_at": "2026-02-10T12:01:30Z" }, "request_id": "req_a1b2c3d4e5f6a1b2c3d4" }
PATCH /api/v1/databases/:uuid

Updates a database. Currently supports renaming.

Scope: databases:write   Idempotency: Required

ParameterTypeDescription
namestringNew name. Same rules as create (lowercase, hyphens, 1-63 chars).
curl -sS -X PATCH "https://polykomos.com/api/v1/databases/d7f3a1b2-..." \ -H "Authorization: Bearer $POLYKOMOS_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"name": "orders-staging-db"}'
import uuid import requests resp = requests.patch( f"https://polykomos.com/api/v1/databases/{db_uuid}", headers={ "Authorization": f"Bearer {api_key}", "Idempotency-Key": str(uuid.uuid4()), }, json={"name": "orders-staging-db"}, ) print(resp.json()["data"])
const resp = await fetch( `https://polykomos.com/api/v1/databases/${dbUuid}`, { method: "PATCH", headers: { Authorization: `Bearer ${API_KEY}`, "Content-Type": "application/json", "Idempotency-Key": crypto.randomUUID(), }, body: JSON.stringify({ name: "orders-staging-db" }), } ); const { data } = await resp.json();
$ch = curl_init("https://polykomos.com/api/v1/databases/$dbUuid"); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PATCH"); curl_setopt($ch, CURLOPT_HTTPHEADER, [ "Authorization: Bearer $apiKey", "Content-Type: application/json", "Idempotency-Key: " . bin2hex(random_bytes(16)), ]); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([ "name" => "orders-staging-db", ])); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $result = json_decode(curl_exec($ch), true); print_r($result["data"]);
require "net/http" require "json" require "securerandom" uri = URI("https://polykomos.com/api/v1/databases/#{db_uuid}") req = Net::HTTP::Patch.new(uri) req["Authorization"] = "Bearer #{api_key}" req["Content-Type"] = "application/json" req["Idempotency-Key"] = SecureRandom.uuid req.body = { name: "orders-staging-db" }.to_json res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) } puts JSON.parse(res.body)["data"]
package main import ( "bytes" "encoding/json" "fmt" "io" "net/http" "github.com/google/uuid" ) func main() { body, _ := json.Marshal(map[string]string{"name": "orders-staging-db"}) req, _ := http.NewRequest("PATCH", "https://polykomos.com/api/v1/databases/"+dbUuid, bytes.NewReader(body)) req.Header.Set("Authorization", "Bearer "+apiKey) req.Header.Set("Content-Type", "application/json") req.Header.Set("Idempotency-Key", uuid.New().String()) resp, _ := http.DefaultClient.Do(req) defer resp.Body.Close() respBody, _ := io.ReadAll(resp.Body) var result map[string]interface{} json.Unmarshal(respBody, &result) fmt.Println(result["data"]) }
200 Response
{ "data": { "object": "database", "uuid": "d7f3a1b2-...", "name": "orders-staging-db", "status": "active", ... }, "request_id": "req_..." }
PATCH /api/v1/databases/:uuid/quotas

Updates per-instance quota overrides for storage, connections, and alert thresholds.

Scope: databases:write   Idempotency: Required

ParameterTypeDescription
uuid requiredstring (path)Database UUID.
storage_hard_limit_gbnumberStorage hard cap override (GB). Use null to clear.
connection_hard_limitintegerConnection hard cap override. Use null to clear.
warning_threshold_pctintegerWarning threshold (1-100). Use null to clear.
curl -sS -X PATCH "https://polykomos.com/api/v1/databases/d7f3a1b2-4c5e-6f7a-8b9c-0d1e2f3a4b5c/quotas" \ -H "Authorization: Bearer $POLYKOMOS_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{ "storage_hard_limit_gb": 10, "connection_hard_limit": 50, "warning_threshold_pct": 80 }'
import uuid import requests resp = requests.patch( "https://polykomos.com/api/v1/databases/d7f3a1b2-4c5e-6f7a-8b9c-0d1e2f3a4b5c/quotas", headers={ "Authorization": f"Bearer {api_key}", "Idempotency-Key": str(uuid.uuid4()), }, json={ "storage_hard_limit_gb": 10, "connection_hard_limit": 50, "warning_threshold_pct": 80, }, ) print(resp.json()["data"])
const resp = await fetch("https://polykomos.com/api/v1/databases/d7f3a1b2-4c5e-6f7a-8b9c-0d1e2f3a4b5c/quotas", { method: "PATCH", headers: { Authorization: `Bearer ${API_KEY}`, "Content-Type": "application/json", "Idempotency-Key": crypto.randomUUID(), }, body: JSON.stringify({ storage_hard_limit_gb: 10, connection_hard_limit: 50, warning_threshold_pct: 80, }), }); const { data } = await resp.json();
200 Response
{ "message": "Database quotas updated.", "data": { "object": "database", "uuid": "d7f3a1b2-4c5e-6f7a-8b9c-0d1e2f3a4b5c", "quotas": { "storage_hard_limit_gb": 10, "connection_hard_limit": 50, "warning_threshold_pct": 80 }, ... }, "request_id": "req_..." }
DELETE /api/v1/databases/:uuid

Deletes a database. Access is revoked immediately. Remote resources are cleaned up after a 24-hour grace period.

Scope: databases:write   Idempotency: Required

curl -sS -X DELETE "https://polykomos.com/api/v1/databases/d7f3a1b2-..." \ -H "Authorization: Bearer $POLYKOMOS_API_KEY" \ -H "Idempotency-Key: $(uuidgen)"
import uuid import requests resp = requests.delete( f"https://polykomos.com/api/v1/databases/{db_uuid}", headers={ "Authorization": f"Bearer {api_key}", "Idempotency-Key": str(uuid.uuid4()), }, ) print(resp.json())
const resp = await fetch( `https://polykomos.com/api/v1/databases/${dbUuid}`, { method: "DELETE", headers: { Authorization: `Bearer ${API_KEY}`, "Idempotency-Key": crypto.randomUUID(), }, } ); console.log(await resp.json());
$ch = curl_init("https://polykomos.com/api/v1/databases/$dbUuid"); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "DELETE"); curl_setopt($ch, CURLOPT_HTTPHEADER, [ "Authorization: Bearer $apiKey", "Idempotency-Key: " . bin2hex(random_bytes(16)), ]); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $result = json_decode(curl_exec($ch), true); print_r($result);
require "net/http" require "json" require "securerandom" uri = URI("https://polykomos.com/api/v1/databases/#{db_uuid}") req = Net::HTTP::Delete.new(uri) req["Authorization"] = "Bearer #{api_key}" req["Idempotency-Key"] = SecureRandom.uuid res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) } puts JSON.parse(res.body)
package main import ( "encoding/json" "fmt" "io" "net/http" "github.com/google/uuid" ) func main() { req, _ := http.NewRequest("DELETE", "https://polykomos.com/api/v1/databases/"+dbUuid, nil) req.Header.Set("Authorization", "Bearer "+apiKey) req.Header.Set("Idempotency-Key", uuid.New().String()) resp, _ := http.DefaultClient.Do(req) defer resp.Body.Close() body, _ := io.ReadAll(resp.Body) var result map[string]interface{} json.Unmarshal(body, &result) fmt.Println(result) }
200 Response
{ "message": "Database deleted. Access was revoked immediately.", "data": { "object": "database", "uuid": "d7f3a1b2-...", "deleted": true, "cancelled_provision_jobs": 0, "destroy_scheduled_at": "2026-02-11 12:00:00", "has_remote_resources": true }, "request_id": "req_..." }
POST /api/v1/databases/:uuid/blueprint_applications

Applies a blueprint to an existing active database. The blueprint's SQL statements are executed in a transaction. Use dry_run: true to validate without making changes.

Scopes: databases:write + blueprints:read   Idempotency: Required

ParameterTypeDescription
uuid requiredstring (path)UUID of the target database.
blueprint_uuid requiredstringUUID of the blueprint to apply.
variablesobjectVariables to pass to the blueprint.
dry_runbooleanIf true, execute in a transaction and roll back. Default: false.
waitbooleanIf true, block until completion. Default: true.
timeoutintegerMax seconds to wait (1-120). Default: 30.
curl -sS -X POST "https://polykomos.com/api/v1/databases/d7f3a1b2-.../blueprint_applications" \ -H "Authorization: Bearer $POLYKOMOS_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{"blueprint_uuid": "b1c2d3e4-...", "dry_run": false}'
import uuid, requests resp = requests.post( f"https://polykomos.com/api/v1/databases/{db_uuid}/blueprint_applications", headers={ "Authorization": f"Bearer {api_key}", "Idempotency-Key": str(uuid.uuid4()), }, json={"blueprint_uuid": blueprint_uuid, "dry_run": False}, ) print(resp.json())
const resp = await fetch( `https://polykomos.com/api/v1/databases/${dbUuid}/blueprint_applications`, { method: "POST", headers: { Authorization: `Bearer ${API_KEY}`, "Content-Type": "application/json", "Idempotency-Key": crypto.randomUUID(), }, body: JSON.stringify({ blueprint_uuid: blueprintUuid, dry_run: false }), } ); console.log(await resp.json());
200 Response
{ "message": "Blueprint applied successfully.", "data": { "object": "blueprint_application", "id": 42, "status": "completed", "is_dry_run": false, "statements_total": 3, "statements_succeeded": 3, "statements_failed": 0, "total_duration_ms": 85, ... }, "request_id": "req_..." }
POST /api/v1/query_executions

Executes a natural language query against a database. The query is translated to SQL using an LLM, validated for safety, and executed on the target database. Daily NLQ limits: Free 10/day, Pro 500/day, Enterprise unlimited.

Scope: queries:write

FieldTypeDescription
database_uuid requiredstringUUID of the target database. Must be active.
query requiredstringNatural language query (max 2000 characters). Example: "show all contacts from Acme Corp"
curl -sS -X POST "https://polykomos.com/api/v1/query_executions" \ -H "Authorization: Bearer $POLYKOMOS_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "database_uuid": "d7f3a1b2-4c5e-6f7a-8b9c-0d1e2f3a4b5c", "query": "show all contacts from Acme Corp" }'
import requests resp = requests.post( "https://polykomos.com/api/v1/query_executions", headers={"Authorization": f"Bearer {api_key}"}, json={ "database_uuid": "d7f3a1b2-4c5e-6f7a-8b9c-0d1e2f3a4b5c", "query": "show all contacts from Acme Corp", }, ) data = resp.json() print(data["sql"]) # Generated SQL print(data["result"]) # Query results
const resp = await fetch("https://polykomos.com/api/v1/query_executions", { method: "POST", headers: { Authorization: `Bearer ${API_KEY}`, "Content-Type": "application/json", }, body: JSON.stringify({ database_uuid: "d7f3a1b2-4c5e-6f7a-8b9c-0d1e2f3a4b5c", query: "show all contacts from Acme Corp", }), }); const { sql, result } = await resp.json(); console.log(sql, result);
$ch = curl_init("https://polykomos.com/api/v1/query_executions"); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_HTTPHEADER, [ "Authorization: Bearer $apiKey", "Content-Type: application/json", ]); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([ "database_uuid" => "d7f3a1b2-4c5e-6f7a-8b9c-0d1e2f3a4b5c", "query" => "show all contacts from Acme Corp", ])); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $result = json_decode(curl_exec($ch), true); print_r($result);
200 Response (SELECT)
{ "success": true, "sql": "SELECT * FROM \"contacts\" WHERE \"company\" = 'Acme Corp' LIMIT 100", "result": { "type": "select", "rows": [ {"id": 1, "name": "Alice Chen", "email": "alice@acme.com", "company": "Acme Corp"} ], "rowCount": 1 }, "query_id": 42, "request_id": "req_..." }
200 Response (INSERT/UPDATE/DELETE)
{ "success": true, "sql": "INSERT INTO \"contacts\" (\"name\", \"email\") VALUES ('Bob', 'bob@example.com')", "result": { "type": "write", "affectedRows": 1 }, "query_id": 43, "request_id": "req_..." }
200 Response (DDL)
{ "success": true, "sql": "CREATE TABLE \"contacts\" (\"id\" SERIAL PRIMARY KEY, ...); CREATE INDEX ...", "result": { "type": "ddl_batch", "statementsExecuted": 2 }, "query_id": 44, "request_id": "req_..." }
500 Error Response
{ "error": { "code": "query_execution_failed", "message": "relation \"contacts\" does not exist", "details": { "sql": "SELECT * FROM \"contacts\" LIMIT 100", "query_id": 45 } }, "request_id": "req_..." }

GET /api/v1/webhook_endpoints

Returns a paginated list of your webhook endpoints.

Scope: webhooks:read

ParameterTypeDescription
limitintegerItems per page (1-100, default 25).
starting_afterintegerID of the last endpoint from the previous page.
curl -sS "https://polykomos.com/api/v1/webhook_endpoints" \ -H "Authorization: Bearer $POLYKOMOS_API_KEY"
import requests resp = requests.get( "https://polykomos.com/api/v1/webhook_endpoints", headers={"Authorization": f"Bearer {api_key}"}, ) endpoints = resp.json()["data"]
const resp = await fetch("https://polykomos.com/api/v1/webhook_endpoints", { headers: { Authorization: `Bearer ${API_KEY}` }, }); const { data } = await resp.json();
$ch = curl_init("https://polykomos.com/api/v1/webhook_endpoints"); curl_setopt($ch, CURLOPT_HTTPHEADER, ["Authorization: Bearer $apiKey"]); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $result = json_decode(curl_exec($ch), true); $endpoints = $result["data"];
require "net/http" require "json" uri = URI("https://polykomos.com/api/v1/webhook_endpoints") req = Net::HTTP::Get.new(uri) req["Authorization"] = "Bearer #{api_key}" res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) } endpoints = JSON.parse(res.body)["data"]
package main import ( "encoding/json" "fmt" "io" "net/http" ) func main() { req, _ := http.NewRequest("GET", "https://polykomos.com/api/v1/webhook_endpoints", nil) req.Header.Set("Authorization", "Bearer "+apiKey) resp, _ := http.DefaultClient.Do(req) defer resp.Body.Close() body, _ := io.ReadAll(resp.Body) var result map[string]interface{} json.Unmarshal(body, &result) endpoints := result["data"] fmt.Println(endpoints) }
200 Response
{ "data": [ { "object": "webhook_endpoint", "id": 7, "url": "https://your-app.com/webhooks/polykomos", "events": ["database.provisioned", "database.deleted"], "status": "active", "last_success_at": "2026-02-10 14:23:01", "last_failure_at": null, "created_at": "2026-02-09 10:00:00" } ], "has_more": false, "request_id": "req_..." }
POST /api/v1/webhook_endpoints

Creates a webhook endpoint. The secret is returned once in the response -- store it securely for signature verification.

Scope: webhooks:write   Idempotency: Required

ParameterTypeDescription
url requiredstringHTTPS URL to receive webhook events.
eventsarrayEvents to subscribe to. Empty = all events.
curl -sS -X POST https://polykomos.com/api/v1/webhook_endpoints \ -H "Authorization: Bearer $POLYKOMOS_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{ "url": "https://your-app.com/webhooks/polykomos", "events": ["database.provisioned", "database.deleted"] }'
import uuid import requests resp = requests.post( "https://polykomos.com/api/v1/webhook_endpoints", headers={ "Authorization": f"Bearer {api_key}", "Idempotency-Key": str(uuid.uuid4()), }, json={ "url": "https://your-app.com/webhooks/polykomos", "events": ["database.provisioned", "database.deleted"], }, ) data = resp.json() secret = data["secret"] # Store this securely!
const resp = await fetch("https://polykomos.com/api/v1/webhook_endpoints", { method: "POST", headers: { Authorization: `Bearer ${API_KEY}`, "Content-Type": "application/json", "Idempotency-Key": crypto.randomUUID(), }, body: JSON.stringify({ url: "https://your-app.com/webhooks/polykomos", events: ["database.provisioned", "database.deleted"], }), }); const { data, secret } = await resp.json(); // Store `secret` securely for signature verification
$ch = curl_init("https://polykomos.com/api/v1/webhook_endpoints"); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_HTTPHEADER, [ "Authorization: Bearer $apiKey", "Content-Type: application/json", "Idempotency-Key: " . bin2hex(random_bytes(16)), ]); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([ "url" => "https://your-app.com/webhooks/polykomos", "events" => ["database.provisioned", "database.deleted"], ])); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $result = json_decode(curl_exec($ch), true); $secret = $result["secret"]; // Store this securely!
require "net/http" require "json" require "securerandom" uri = URI("https://polykomos.com/api/v1/webhook_endpoints") req = Net::HTTP::Post.new(uri) req["Authorization"] = "Bearer #{api_key}" req["Content-Type"] = "application/json" req["Idempotency-Key"] = SecureRandom.uuid req.body = { url: "https://your-app.com/webhooks/polykomos", events: ["database.provisioned", "database.deleted"] }.to_json res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) } data = JSON.parse(res.body) secret = data["secret"] # Store this securely!
package main import ( "bytes" "encoding/json" "fmt" "io" "net/http" "github.com/google/uuid" ) func main() { body, _ := json.Marshal(map[string]interface{}{ "url": "https://your-app.com/webhooks/polykomos", "events": []string{"database.provisioned", "database.deleted"}, }) req, _ := http.NewRequest("POST", "https://polykomos.com/api/v1/webhook_endpoints", bytes.NewReader(body)) req.Header.Set("Authorization", "Bearer "+apiKey) req.Header.Set("Content-Type", "application/json") req.Header.Set("Idempotency-Key", uuid.New().String()) resp, _ := http.DefaultClient.Do(req) defer resp.Body.Close() respBody, _ := io.ReadAll(resp.Body) var result map[string]interface{} json.Unmarshal(respBody, &result) secret := result["secret"] // Store this securely! fmt.Println(secret) }
201 Response
{ "message": "Webhook endpoint created.", "data": { "object": "webhook_endpoint", "id": 7, "url": "https://your-app.com/webhooks/polykomos", "events": ["database.provisioned", "database.deleted"], "status": "active", "created_at": "2026-02-10 12:00:00" }, "secret": "whsec_a1b2c3d4e5f6...", "request_id": "req_..." }
DELETE /api/v1/webhook_endpoints/:id

Revokes a webhook endpoint. No further events will be delivered to it.

Scope: webhooks:write   Idempotency: Required

curl -sS -X DELETE "https://polykomos.com/api/v1/webhook_endpoints/7" \ -H "Authorization: Bearer $POLYKOMOS_API_KEY" \ -H "Idempotency-Key: $(uuidgen)"
import uuid import requests resp = requests.delete( "https://polykomos.com/api/v1/webhook_endpoints/7", headers={ "Authorization": f"Bearer {api_key}", "Idempotency-Key": str(uuid.uuid4()), }, )
const resp = await fetch("https://polykomos.com/api/v1/webhook_endpoints/7", { method: "DELETE", headers: { Authorization: `Bearer ${API_KEY}`, "Idempotency-Key": crypto.randomUUID(), }, }); console.log(await resp.json());
$ch = curl_init("https://polykomos.com/api/v1/webhook_endpoints/7"); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "DELETE"); curl_setopt($ch, CURLOPT_HTTPHEADER, [ "Authorization: Bearer $apiKey", "Idempotency-Key: " . bin2hex(random_bytes(16)), ]); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $result = json_decode(curl_exec($ch), true); print_r($result);
require "net/http" require "json" require "securerandom" uri = URI("https://polykomos.com/api/v1/webhook_endpoints/7") req = Net::HTTP::Delete.new(uri) req["Authorization"] = "Bearer #{api_key}" req["Idempotency-Key"] = SecureRandom.uuid res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) } puts JSON.parse(res.body)
package main import ( "encoding/json" "fmt" "io" "net/http" "github.com/google/uuid" ) func main() { req, _ := http.NewRequest("DELETE", "https://polykomos.com/api/v1/webhook_endpoints/7", nil) req.Header.Set("Authorization", "Bearer "+apiKey) req.Header.Set("Idempotency-Key", uuid.New().String()) resp, _ := http.DefaultClient.Do(req) defer resp.Body.Close() body, _ := io.ReadAll(resp.Body) var result map[string]interface{} json.Unmarshal(body, &result) fmt.Println(result) }
200 Response
{ "message": "Webhook endpoint revoked.", "data": { "id": 7 }, "request_id": "req_..." }
POST /api/v1/webhook_endpoints/:id/test_deliveries

Sends a test ping event to the endpoint. Use this to verify your webhook handler is working.

Scope: webhooks:write

curl -sS -X POST "https://polykomos.com/api/v1/webhook_endpoints/7/test_deliveries" \ -H "Authorization: Bearer $POLYKOMOS_API_KEY"
import requests resp = requests.post( "https://polykomos.com/api/v1/webhook_endpoints/7/test_deliveries", headers={"Authorization": f"Bearer {api_key}"}, )
const resp = await fetch( "https://polykomos.com/api/v1/webhook_endpoints/7/test_deliveries", { method: "POST", headers: { Authorization: `Bearer ${API_KEY}` }, } ); console.log(await resp.json());
$ch = curl_init("https://polykomos.com/api/v1/webhook_endpoints/7/test_deliveries"); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_HTTPHEADER, ["Authorization: Bearer $apiKey"]); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $result = json_decode(curl_exec($ch), true); print_r($result);
require "net/http" require "json" uri = URI("https://polykomos.com/api/v1/webhook_endpoints/7/test_deliveries") req = Net::HTTP::Post.new(uri) req["Authorization"] = "Bearer #{api_key}" res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) } puts JSON.parse(res.body)
package main import ( "encoding/json" "fmt" "io" "net/http" ) func main() { req, _ := http.NewRequest("POST", "https://polykomos.com/api/v1/webhook_endpoints/7/test_deliveries", nil) req.Header.Set("Authorization", "Bearer "+apiKey) resp, _ := http.DefaultClient.Do(req) defer resp.Body.Close() body, _ := io.ReadAll(resp.Body) var result map[string]interface{} json.Unmarshal(body, &result) fmt.Println(result) }
200 Response
{ "data": { "object": "webhook_delivery", "id": 42, "endpoint_id": 7, "event_type": "ping", "status": "delivered", "response_code": 200, "error_message": null, "created_at": "2026-02-10 12:00:00" }, "request_id": "req_..." }
GET /api/v1/webhook_endpoints/:id/deliveries

Returns a paginated list of delivery attempts for a specific webhook endpoint. Useful for debugging delivery failures.

Scope: webhooks:read

ParameterTypeDescription
limitintegerItems per page (1-100, default 25).
starting_afterintegerID of the last delivery from the previous page.
curl -sS "https://polykomos.com/api/v1/webhook_endpoints/7/deliveries?limit=10" \ -H "Authorization: Bearer $POLYKOMOS_API_KEY"
import requests resp = requests.get( "https://polykomos.com/api/v1/webhook_endpoints/7/deliveries", headers={"Authorization": f"Bearer {api_key}"}, params={"limit": 10}, ) deliveries = resp.json()["data"]
const resp = await fetch( "https://polykomos.com/api/v1/webhook_endpoints/7/deliveries?limit=10", { headers: { Authorization: `Bearer ${API_KEY}` } } ); const { data } = await resp.json();
$ch = curl_init("https://polykomos.com/api/v1/webhook_endpoints/7/deliveries?limit=10"); curl_setopt($ch, CURLOPT_HTTPHEADER, ["Authorization: Bearer $apiKey"]); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $result = json_decode(curl_exec($ch), true); $deliveries = $result["data"];
require "net/http" require "json" uri = URI("https://polykomos.com/api/v1/webhook_endpoints/7/deliveries?limit=10") req = Net::HTTP::Get.new(uri) req["Authorization"] = "Bearer #{api_key}" res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) } deliveries = JSON.parse(res.body)["data"]
package main import ( "encoding/json" "fmt" "io" "net/http" ) func main() { req, _ := http.NewRequest("GET", "https://polykomos.com/api/v1/webhook_endpoints/7/deliveries?limit=10", nil) req.Header.Set("Authorization", "Bearer "+apiKey) resp, _ := http.DefaultClient.Do(req) defer resp.Body.Close() body, _ := io.ReadAll(resp.Body) var result map[string]interface{} json.Unmarshal(body, &result) deliveries := result["data"] fmt.Println(deliveries) }
200 Response
{ "data": [ { "object": "webhook_delivery", "id": 42, "endpoint_id": 7, "event_type": "database.provisioned", "status": "delivered", "response_code": 200, "error_message": null, "attempt_count": 1, "created_at": "2026-02-10 14:23:01" } ], "has_more": false, "request_id": "req_..." }

GET /api/v1/blueprints

Returns a paginated list of your blueprints. System blueprints shared with all users are also included.

Scope: blueprints:read

ParameterTypeDescription
limitintegerItems per page (1-100, default 25).
starting_afterstringUUID of the last blueprint from the previous page.
curl -sS "https://polykomos.com/api/v1/blueprints?limit=10" \ -H "Authorization: Bearer $POLYKOMOS_API_KEY"
resp = requests.get( "https://polykomos.com/api/v1/blueprints", params={"limit": 10}, headers={"Authorization": f"Bearer {api_key}"}, ) print(resp.json())
const resp = await fetch("https://polykomos.com/api/v1/blueprints?limit=10", { headers: { Authorization: `Bearer ${API_KEY}` }, }); console.log(await resp.json());
200 Response
{ "data": [ { "object": "blueprint", "uuid": "b1c2d3e4-...", "name": "seed-contacts", "slug": "seed-contacts", "description": "Creates a contacts table with sample data", "content_type": "sql", "version": 1, "size_bytes": 482, "is_system_blueprint": false, "variables": null, "metadata": null, "created_at": "2026-02-15T10:00:00Z", "updated_at": "2026-02-15T10:00:00Z" } ], "has_more": false, "request_id": "req_..." }
POST /api/v1/blueprints

Creates a new blueprint. The SQL content is validated before saving.

Scope: blueprints:write   Idempotency: Required

FieldTypeDescription
name requiredstringHuman-readable name for the blueprint.
sql_content requiredstringSQL statements to include in the blueprint.
descriptionstringOptional description of what the blueprint does.
variablesobjectOptional variable definitions for blueprint SQL substitution.
curl -sS -X POST "https://polykomos.com/api/v1/blueprints" \ -H "Authorization: Bearer $POLYKOMOS_API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{ "name": "seed-contacts", "sql_content": "CREATE TABLE contacts (id SERIAL PRIMARY KEY, name VARCHAR(255) NOT NULL);", "description": "Creates a contacts table" }'
import uuid, requests resp = requests.post( "https://polykomos.com/api/v1/blueprints", headers={ "Authorization": f"Bearer {api_key}", "Idempotency-Key": str(uuid.uuid4()), }, json={ "name": "seed-contacts", "sql_content": "CREATE TABLE contacts (id SERIAL PRIMARY KEY, name VARCHAR(255) NOT NULL);", "description": "Creates a contacts table", }, ) print(resp.json())
const resp = await fetch("https://polykomos.com/api/v1/blueprints", { method: "POST", headers: { Authorization: `Bearer ${API_KEY}`, "Content-Type": "application/json", "Idempotency-Key": crypto.randomUUID(), }, body: JSON.stringify({ name: "seed-contacts", sql_content: "CREATE TABLE contacts (id SERIAL PRIMARY KEY, name VARCHAR(255) NOT NULL);", description: "Creates a contacts table", }), }); console.log(await resp.json());
201 Response
{ "message": "Blueprint created.", "data": { "object": "blueprint", "uuid": "b1c2d3e4-...", "name": "seed-contacts", "slug": "seed-contacts", "description": "Creates a contacts table", "content_type": "sql", "version": 1, ... }, "request_id": "req_..." }
GET /api/v1/blueprints/:uuid

Returns a single blueprint including the full sql_content field.

Scope: blueprints:read

curl -sS "https://polykomos.com/api/v1/blueprints/b1c2d3e4-..." \ -H "Authorization: Bearer $POLYKOMOS_API_KEY"
resp = requests.get( f"https://polykomos.com/api/v1/blueprints/{blueprint_uuid}", headers={"Authorization": f"Bearer {api_key}"}, ) print(resp.json())
const resp = await fetch( `https://polykomos.com/api/v1/blueprints/${bpUuid}`, { headers: { Authorization: `Bearer ${API_KEY}` } } ); console.log(await resp.json());
200 Response
{ "data": { "object": "blueprint", "uuid": "b1c2d3e4-...", "name": "seed-contacts", "sql_content": "CREATE TABLE contacts (id SERIAL PRIMARY KEY, name VARCHAR(255) NOT NULL);", ... }, "request_id": "req_..." }
PATCH /api/v1/blueprints/:uuid

Updates a blueprint. System blueprints cannot be modified. Updating sql_content increments the version.

Scope: blueprints:write

FieldTypeDescription
namestringUpdated name.
descriptionstringUpdated description.
sql_contentstringUpdated SQL content (triggers re-validation and version bump).
variablesobjectUpdated variable definitions.
curl -sS -X PATCH "https://polykomos.com/api/v1/blueprints/b1c2d3e4-..." \ -H "Authorization: Bearer $POLYKOMOS_API_KEY" \ -H "Content-Type: application/json" \ -d '{"name": "updated-name", "description": "Updated description"}'
200 Response
{ "message": "Blueprint updated.", "data": { "object": "blueprint", "uuid": "b1c2d3e4-...", "name": "updated-name", "version": 2, ... }, "request_id": "req_..." }
DELETE /api/v1/blueprints/:uuid

Deletes a blueprint (soft delete). System blueprints cannot be deleted.

Scope: blueprints:write

curl -sS -X DELETE "https://polykomos.com/api/v1/blueprints/b1c2d3e4-..." \ -H "Authorization: Bearer $POLYKOMOS_API_KEY"
200 Response
{ "message": "Blueprint deleted.", "data": { "object": "blueprint", "uuid": "b1c2d3e4-...", "deleted": true }, "request_id": "req_..." }
POST /api/v1/blueprint_validations

Validates SQL content without creating a blueprint. Returns validation results including statement count, errors, and warnings.

Scope: blueprints:read

FieldTypeDescription
sql_content requiredstringSQL statements to validate.
curl -sS -X POST "https://polykomos.com/api/v1/blueprint_validations" \ -H "Authorization: Bearer $POLYKOMOS_API_KEY" \ -H "Content-Type: application/json" \ -d '{"sql_content": "CREATE TABLE contacts (id SERIAL PRIMARY KEY);"}'
200 Response
{ "data": { "valid": true, "statement_count": 1, "errors": [], "warnings": [], "manifest": { ... } }, "request_id": "req_..." }
GET /api/v1/blueprint_applications/:id

Returns a single blueprint application by ID. Use this to check the status and execution log of a blueprint that was applied to a database.

Scope: blueprints:read

ParameterTypeDescription
id requiredinteger (path)ID of the blueprint application.
curl -sS "https://polykomos.com/api/v1/blueprint_applications/42" \ -H "Authorization: Bearer $POLYKOMOS_API_KEY"
200 Response
{ "data": { "object": "blueprint_application", "id": 42, "blueprint_id": 7, "blueprint_version": 1, "database_instance_id": 15, "status": "completed", "is_dry_run": false, "statements_total": 3, "statements_succeeded": 3, "statements_failed": 0, "total_duration_ms": 85, "error_message": null, "started_at": "2026-02-15T10:01:00Z", "completed_at": "2026-02-15T10:01:00Z", "created_at": "2026-02-15T10:01:00Z" }, "request_id": "req_..." }

Webhooks

Webhooks notify your application of lifecycle events in real time.

Events

EventFires when
database.provisioning_startedA new database has been queued for provisioning.
database.provisionedA database is active and ready to accept connections.
database.deletedA database has been deleted.
pingSent when you use the test endpoint.

Payload Format

{ "event": "database.provisioned", "timestamp": "2026-02-10T14:23:01+00:00", "data": { "object": "database", "uuid": "d7f3a1b2-...", "name": "orders-prod-db", "status": "active", ... } }

Signature Verification

Every delivery includes an X-Polykomos-Signature header with an HMAC-SHA256 signature of the raw request body, using your webhook secret.

Also included: X-Polykomos-Event header with the event type.

import hmac, hashlib def verify_signature(payload: bytes, signature: str, secret: str) -> bool: expected = "sha256=" + hmac.new( secret.encode(), payload, hashlib.sha256 ).hexdigest() return hmac.compare_digest(expected, signature)
import { createHmac, timingSafeEqual } from "crypto"; function verifySignature(payload, signature, secret) { const expected = Buffer.from( "sha256=" + createHmac("sha256", secret).update(payload).digest("hex") ); const actual = Buffer.from(signature); if (expected.length !== actual.length) return false; return timingSafeEqual(expected, actual); }
function verifySignature(string $payload, string $signature, string $secret): bool { $expected = 'sha256=' . hash_hmac('sha256', $payload, $secret); return hash_equals($expected, $signature); }
require "openssl" def verify_signature(payload, signature, secret) expected = "sha256=" + OpenSSL::HMAC.hexdigest("SHA256", secret, payload) Rack::Utils.secure_compare(expected, signature) end