openapi: 3.0.3
info:
title: Athena RS
version: 2.9.0
description: |
Athena gateway API and driver.
Every operation returns at least one 2xx (success) and one 5xx (server error) response; 3xx (redirect) is optional where applicable.
servers:
- url: https://athena-db.com
paths:
/:
get:
summary: API root and route listing
description: Returns health status and a list of all available routes with methods and summaries (PostgREST-style).
responses:
'200':
description: OK
content:
application/json:
schema:
type: object
properties:
message:
type: string
example: athena is online
version:
type: string
description: API version (cargo_toml_version)
athena_api:
type: string
example: online
athena_deadpool:
type: string
example: online
athena_scylladb:
type: string
enum:
- online
- offline
cargo_toml_version:
type: string
routes:
type: array
description: All available routes with path, methods, and summary
items:
type: object
properties:
path:
type: string
example: /gateway/data
methods:
type: array
items:
type: string
example:
- POST
summary:
type: string
'500':
$ref: '#/components/responses/DefaultServerError5xx'
/ping:
get:
summary: Health check
description: Returns `pong` so orchestrators and load balancers can verify the process is alive.
responses:
'200':
description: Pong response
content:
text/plain:
schema:
type: string
example: pong
'500':
$ref: '#/components/responses/DefaultServerError5xx'
/health/cluster:
get:
summary: Cluster mirror health and version checks
description: Checks Athena mirror domains, returns reachability, latency, throughput, and reported version metadata.
responses:
'200':
description: Cluster health details
content:
application/json:
schema:
$ref: '#/components/schemas/ClusterHealthResponse'
'500':
$ref: '#/components/responses/DefaultServerError5xx'
/management/capabilities:
get:
summary: List management API capabilities for a client
description: Requires `X-Athena-Client` and a client-bound API key with `management.read`.
parameters:
- in: header
name: X-Athena-Client
required: true
schema:
type: string
- in: header
name: apikey
required: true
schema:
type: string
- in: header
name: x-api-key
schema:
type: string
description: optional API key mirror of the `apikey` header
responses:
'200':
description: Management capability details
content:
application/json:
schema:
$ref: '#/components/schemas/ManagementCapabilitiesEnvelope'
'400':
description: Missing or unknown X-Athena-Client
'401':
description: Missing or invalid API key
'403':
description: API key is not client-bound or lacks management.read
'500':
$ref: '#/components/responses/DefaultServerError5xx'
/management/tables:
post:
summary: Create a managed table
description: Requires `X-Athena-Client` and a client-bound API key with `management.tables.write`.
parameters:
- in: header
name: X-Athena-Client
required: true
schema:
type: string
- in: header
name: apikey
required: true
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateTableRequest'
responses:
'201':
description: Table created
content:
application/json:
schema:
type: object
'400':
description: Invalid payload
'401':
description: Missing or invalid API key
'403':
description: Missing management.tables.write or key is not client-bound
'409':
description: Table already exists
'503':
description: database_audit_log is not available in the target database
/management/tables/{table_name}:
patch:
summary: Apply safe additive ALTER TABLE operations
description: Requires `X-Athena-Client` and a client-bound API key with `management.tables.write`.
parameters:
- in: path
name: table_name
required: true
schema:
type: string
- in: header
name: X-Athena-Client
required: true
schema:
type: string
- in: header
name: apikey
required: true
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/EditTableRequest'
responses:
'200':
description: Table updated
'400':
description: Invalid payload or unsupported alteration
'401':
description: Missing or invalid API key
'403':
description: Missing management.tables.write or key is not client-bound
'404':
description: Table not found
'503':
description: database_audit_log is not available in the target database
delete:
summary: Drop a managed table
description: Requires `X-Athena-Client` and a client-bound API key with `management.tables.drop`.
parameters:
- in: path
name: table_name
required: true
schema:
type: string
- in: header
name: X-Athena-Client
required: true
schema:
type: string
- in: header
name: apikey
required: true
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/DropTableRequest'
responses:
'200':
description: Table dropped
'401':
description: Missing or invalid API key
'403':
description: Missing management.tables.drop or key is not client-bound
'404':
description: Table not found
'503':
description: database_audit_log is not available in the target database
/management/tables/{table_name}/columns/{column_name}:
delete:
summary: Drop a managed table column
description: Requires `X-Athena-Client` and a client-bound API key with `management.columns.drop`.
parameters:
- in: path
name: table_name
required: true
schema:
type: string
- in: path
name: column_name
required: true
schema:
type: string
- in: header
name: X-Athena-Client
required: true
schema:
type: string
- in: header
name: apikey
required: true
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/DropColumnRequest'
responses:
'200':
description: Column dropped
'400':
description: Invalid payload or reserved column
'401':
description: Missing or invalid API key
'403':
description: Missing management.columns.drop or key is not client-bound
'404':
description: Column not found
'503':
description: database_audit_log is not available in the target database
/management/indexes:
post:
summary: Create an index
description: Requires `X-Athena-Client` and a client-bound API key with `management.indexes.write`.
parameters:
- in: header
name: X-Athena-Client
required: true
schema:
type: string
- in: header
name: apikey
required: true
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateIndexRequest'
responses:
'201':
description: Index created
'400':
description: Invalid payload
'401':
description: Missing or invalid API key
'403':
description: Missing management.indexes.write or key is not client-bound
'404':
description: Table not found
'409':
description: Index already exists
'503':
description: database_audit_log is not available in the target database
/management/indexes/{index_name}:
delete:
summary: Drop an index
description: Requires `X-Athena-Client` and a client-bound API key with `management.indexes.drop`.
parameters:
- in: path
name: index_name
required: true
schema:
type: string
- in: header
name: X-Athena-Client
required: true
schema:
type: string
- in: header
name: apikey
required: true
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/DropIndexRequest'
responses:
'200':
description: Index dropped
'401':
description: Missing or invalid API key
'403':
description: Missing management.indexes.drop or key is not client-bound
'404':
description: Index not found
'503':
description: database_audit_log is not available in the target database
/management/extensions/install:
post:
summary: Install a Postgres extension
description: |
Installs an allowlisted Postgres extension on the selected `X-Athena-Client` database.
Requires a client-bound API key with `management.extensions.write` and an existing `public.database_audit_log`.
parameters:
- in: header
name: X-Athena-Client
required: true
schema:
type: string
- in: header
name: apikey
required: true
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- extension_name
properties:
extension_name:
type: string
description: Extension to install (allowlisted).
example: pgcrypto
if_not_exists:
type: boolean
default: false
responses:
'200':
description: Extension installed
'400':
description: Invalid payload or extension is not allowlisted
'401':
description: Missing or invalid API key
'403':
description: Missing management.extensions.write or key is not client-bound
'503':
description: database_audit_log is not available in the target database
/query/sql:
post:
summary: Execute SQL using selected driver
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
query:
type: string
driver:
type: string
enum:
- athena
- postgresql
- supabase
db_name:
type: string
required:
- query
- driver
- db_name
responses:
'200':
description: Query executed
content:
application/json:
schema:
type: object
'400':
description: Invalid driver
'500':
description: Driver execution failed
'503':
description: Athena/Scylla unavailable
/gateway/fetch:
post:
summary: Fetch data with conditions
parameters:
- in: header
name: X-User-Id
schema:
type: string
- in: header
name: X-Athena-Client
schema:
type: string
- in: header
name: X-Strip-Nulls
schema:
type: string
- in: header
name: apikey
schema:
type: string
- in: header
name: x-api-key
description: optional API key mirror of the `apikey` header
schema:
type: string
- in: header
name: x-supabase-url
description: Required when X-Athena-Client is custom_supabase
schema:
type: string
format: uri
- in: header
name: x-supabase-key
description: Required when X-Athena-Client is custom_supabase
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
view_name:
type: string
table_name:
type: string
columns:
oneOf:
- type: array
items:
type: string
- type: string
conditions:
type: array
items:
type: object
properties:
eq_column:
type: string
eq_value:
type: string
limit:
type: integer
current_page:
type: integer
page_size:
type: integer
offset:
type: integer
total_pages:
type: integer
strip_nulls:
type: boolean
group_by:
type: string
description: Column name to group results by
time_granularity:
type: string
enum:
- day
- hour
- minute
description: Time granularity for grouping timestamp data
aggregation_column:
type: string
description: Column to aggregate (required when using aggregation_strategy)
aggregation_strategy:
type: string
enum:
- cumulative_sum
description: Aggregation strategy to apply (requires aggregation_column)
aggregation_dedup:
type: boolean
description: Whether to deduplicate during aggregation
sortBy:
type: object
description: Optional sort (camelCase). Use sort_by for snake_case.
properties:
field:
type: string
description: Column name to sort by
direction:
type: string
enum:
- asc
- desc
- ascending
- descending
default: asc
sort_by:
type: object
description: Optional sort (snake_case). Same shape as sortBy.
properties:
field:
type: string
direction:
type: string
enum:
- asc
- desc
- ascending
- descending
required:
- conditions
responses:
'200':
description: OK
'400':
description: Bad request
'500':
description: Internal error
/gateway/data:
post:
summary: Legacy alias for `/gateway/fetch`
description: Mirrors `/gateway/fetch` for clients still calling `/gateway/data` with the same payload/response envelope.
parameters:
- in: header
name: X-User-Id
schema:
type: string
- in: header
name: X-Athena-Client
schema:
type: string
- in: header
name: X-Strip-Nulls
schema:
type: string
- in: header
name: apikey
schema:
type: string
- in: header
name: x-api-key
description: optional API key mirror of the `apikey` header
schema:
type: string
- in: header
name: x-supabase-url
description: Required when X-Athena-Client is custom_supabase
schema:
type: string
format: uri
- in: header
name: x-supabase-key
description: Required when X-Athena-Client is custom_supabase
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
view_name:
type: string
table_name:
type: string
columns:
oneOf:
- type: array
items:
type: string
- type: string
conditions:
type: array
items:
type: object
properties:
eq_column:
type: string
eq_value:
type: string
limit:
type: integer
current_page:
type: integer
page_size:
type: integer
offset:
type: integer
total_pages:
type: integer
strip_nulls:
type: boolean
group_by:
type: string
description: Column name to group results by
time_granularity:
type: string
enum:
- day
- hour
- minute
description: Time granularity for grouping timestamp data
aggregation_column:
type: string
description: Column to aggregate (required when using aggregation_strategy)
aggregation_strategy:
type: string
enum:
- cumulative_sum
description: Aggregation strategy to apply (requires aggregation_column)
aggregation_dedup:
type: boolean
description: Whether to deduplicate during aggregation
sortBy:
type: object
description: Optional sort (camelCase). Use sort_by for snake_case.
properties:
field:
type: string
direction:
type: string
enum:
- asc
- desc
- ascending
- descending
sort_by:
type: object
description: Optional sort (snake_case). Same shape as sortBy.
properties:
field:
type: string
direction:
type: string
enum:
- asc
- desc
- ascending
- descending
required:
- conditions
responses:
'200':
description: OK
'400':
description: Bad request
'500':
description: Internal error
/data:
get:
summary: Fetch data via GET
parameters:
- in: query
name: view
required: true
schema:
type: string
- in: query
name: eq_column
required: true
schema:
type: string
- in: query
name: eq_value
required: true
schema:
type: string
- in: query
name: columns
schema:
type: string
- in: query
name: limit
schema:
type: integer
- in: query
name: current_page
schema:
type: integer
- in: query
name: page_size
schema:
type: integer
- in: query
name: offset
schema:
type: integer
- in: query
name: total_pages
schema:
type: integer
- in: query
name: strip_nulls
schema:
type: boolean
- in: query
name: sort_by
schema:
type: string
description: Column name to sort by (forwarded as sortBy.field in the internal POST)
- in: query
name: sort_direction
schema:
type: string
enum:
- asc
- desc
- ascending
- descending
description: Sort direction (default asc)
- in: query
name: group_by
schema:
type: string
description: Column name to group results by
- in: query
name: time_granularity
schema:
type: string
enum:
- day
- hour
- minute
description: Time granularity for grouping timestamp data
- in: query
name: aggregation_column
schema:
type: string
description: Column to aggregate (required when using aggregation_strategy)
- in: query
name: aggregation_strategy
schema:
type: string
enum:
- cumulative_sum
description: Aggregation strategy to apply (requires aggregation_column)
- in: query
name: aggregation_dedup
schema:
type: boolean
description: Whether to deduplicate during aggregation
- in: header
name: X-User-Id
schema:
type: string
- in: header
name: X-Athena-Client
schema:
type: string
- in: header
name: X-Strip-Nulls
schema:
type: string
- in: header
name: apikey
schema:
type: string
- in: header
name: x-api-key
description: optional API key mirror of the `apikey` header
schema:
type: string
- in: header
name: x-supabase-url
description: Optional custom Supabase URL when X-Athena-Client is custom_supabase
schema:
type: string
format: uri
- in: header
name: x-supabase-key
description: Optional custom Supabase key when X-Athena-Client is custom_supabase
schema:
type: string
responses:
'200':
description: OK
'400':
description: Bad request
'500':
description: Internal error
/gateway/insert:
put:
summary: Insert a row into a table
parameters:
- in: header
name: X-User-Id
schema:
type: string
- in: header
name: X-Company-Id
required: true
schema:
type: string
- in: header
name: X-Organization-Id
required: true
schema:
type: string
- in: header
name: X-Publish-Event
schema:
type: string
- in: header
name: X-Athena-Client
schema:
type: string
- in: header
name: apikey
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
table_name:
type: string
insert_body:
type: object
update_body:
type: object
required:
- table_name
- insert_body
responses:
'200':
description: Inserted
'400':
description: Bad request
'409':
description: Conflict
'500':
description: Internal error
/gateway/delete:
delete:
summary: Delete a row by id
parameters:
- in: header
name: X-User-Id
schema:
type: string
- in: header
name: X-Company-Id
required: true
schema:
type: string
- in: header
name: X-Organization-Id
required: true
schema:
type: string
- in: header
name: X-Athena-Client
schema:
type: string
- in: header
name: apikey
schema:
type: string
- in: header
name: x-supabase-url
description: Optional custom Supabase URL when X-Athena-Client is custom_supabase
schema:
type: string
format: uri
- in: header
name: x-supabase-key
description: Optional custom Supabase key when X-Athena-Client is custom_supabase
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
table_name:
type: string
resource_id:
type: string
required:
- table_name
- resource_id
responses:
'200':
description: Deleted
'400':
description: Bad request
'500':
description: Internal error
/gateway/update:
post:
summary: Fetch or update data using a SQLx client (same payload as /gateway/fetch)
parameters:
- in: header
name: X-User-Id
schema:
type: string
- in: header
name: X-Athena-Client
description: selects which PostgreSQL pool to use
schema:
type: string
- in: header
name: X-Strip-Nulls
schema:
type: string
- in: header
name: apikey
schema:
type: string
- in: header
name: x-api-key
description: optional API key mirror of the `apikey` header
schema:
type: string
- in: header
name: x-supabase-url
description: Required when X-Athena-Client is custom_supabase
schema:
type: string
format: uri
- in: header
name: x-supabase-key
description: Required when X-Athena-Client is custom_supabase
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
view_name:
type: string
table_name:
type: string
columns:
oneOf:
- type: array
items:
type: string
- type: string
conditions:
type: array
items:
type: object
properties:
eq_column:
type: string
eq_value:
type: string
limit:
type: integer
current_page:
type: integer
page_size:
type: integer
offset:
type: integer
total_pages:
type: integer
strip_nulls:
type: boolean
group_by:
type: string
description: Column name to group results by
time_granularity:
type: string
enum:
- day
- hour
- minute
description: Time granularity for grouping timestamp data
aggregation_column:
type: string
description: Column to aggregate (required when using aggregation_strategy)
aggregation_strategy:
type: string
enum:
- cumulative_sum
description: Aggregation strategy to apply (requires aggregation_column)
aggregation_dedup:
type: boolean
description: Whether to deduplicate during aggregation
required:
- conditions
responses:
'200':
description: OK
'400':
description: Bad request
'500':
description: Internal error
/gateway/query:
post:
summary: Run a raw SQL query against the selected PostgreSQL pool
parameters:
- in: header
name: X-Athena-Client
description: selects which PostgreSQL pool the SQL executes against
required: true
schema:
type: string
- in: header
name: x-api-key
description: optional API key mirror of the `apikey` header in the body
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
query:
description: raw SQL to execute
type: string
required:
- query
responses:
'200':
description: OK
'400':
description: Bad request
'500':
description: Internal error
/rest/v1/{table}:
get:
summary: Query a table using PostgREST-style filters
description: |
Mirrors the Supabase PostgREST query syntax. Supply filter expressions (`column.eq=value`, `column.lt=value`, `or=(cond1,cond2)`, etc.), `select`, `limit`, `offset`, `order`, and the optional `Range` header (`items=0-24`). The handler also honors `Prefer: return=minimal`.
parameters:
- in: path
name: table
required: true
schema:
type: string
description: Target table name (sanitized before execution).
- in: header
name: X-Athena-Client
required: true
schema:
type: string
description: Selects which Postgres pool executes the query.
- in: header
name: apikey
required: true
schema:
type: string
description: Gateway API key (can also be passed via Authorization or x-api-key).
- in: header
name: x-api-key
schema:
type: string
description: Mirror of `apikey` useful for proxies.
- in: query
name: select
schema:
type: string
description: PostgREST `select` clause (comma separated columns).
- in: query
name: limit
schema:
type: integer
description: Maximum number of rows to return (default 100).
- in: query
name: offset
schema:
type: integer
description: Row offset (default 0).
- in: query
name: order
schema:
type: string
description: Column ordering using `.asc`/`.desc` (e.g. `id.desc`).
- in: query
name: or
schema:
type: string
description: PostgREST `or` expression to build grouped filters (`(a.eq.1,b.eq.2)`).
- in: header
name: Range
schema:
type: string
description: Optional `items=start-end` range header that overrides offset/limit.
responses:
'200':
description: Rows fetched (Content-Range header reports `items start-end/total`).
headers:
Content-Range:
description: items start-end/*
schema:
type: string
content:
application/json:
schema:
type: object
properties:
data:
type: array
items:
type: object
'400':
description: Invalid filters or missing headers
'500':
description: Internal error
post:
summary: Insert or upsert rows via the REST gateway
description: |
Accepts a single object or array payload. Set `Prefer: return=minimal` for HTTP 204 responses and `Prefer: resolution=merge-duplicates` for upserts.
parameters:
- in: path
name: table
required: true
schema:
type: string
- in: header
name: X-Athena-Client
required: true
schema:
type: string
- in: header
name: apikey
required: true
schema:
type: string
- in: header
name: x-api-key
schema:
type: string
- in: header
name: Prefer
schema:
type: string
description: Use `return=minimal` for 204 or `resolution=merge-duplicates` for UPSERT.
requestBody:
required: true
content:
application/json:
schema:
oneOf:
- type: object
- type: array
items:
type: object
responses:
'200':
description: Rows inserted or upserted
content:
application/json:
schema:
type: object
properties:
data:
type: array
items:
type: object
'204':
description: 'Insert succeeded with Prefer: return=minimal'
'400':
description: Invalid payload or headers
'500':
description: Internal error
patch:
summary: Update rows filtered via PostgREST expressions
description: |
Filters are required (`column.eq=value`, `column.lte=value`, `or=(...)`). The request body must be an object describing the columns to patch. `Prefer: return=minimal` controls whether the response returns data.
parameters:
- in: path
name: table
required: true
schema:
type: string
- in: header
name: X-Athena-Client
required: true
schema:
type: string
- in: header
name: apikey
required: true
schema:
type: string
- in: header
name: x-api-key
schema:
type: string
- in: header
name: Prefer
schema:
type: string
description: Set `return=minimal` for HTTP 204.
requestBody:
required: true
content:
application/json:
schema:
type: object
responses:
'200':
description: Rows updated
content:
application/json:
schema:
type: object
properties:
data:
type: array
items:
type: object
'204':
description: 'Update succeeded with Prefer: return=minimal'
'400':
description: Missing filters or invalid payload
'500':
description: Internal error
delete:
summary: Delete rows using PostgREST-style filters
description: |
Filters are mandatory. Use the same query syntax as GET and include `Prefer: return=minimal` for HTTP 204 responses.
parameters:
- in: path
name: table
required: true
schema:
type: string
- in: header
name: X-Athena-Client
required: true
schema:
type: string
- in: header
name: apikey
required: true
schema:
type: string
- in: header
name: x-api-key
schema:
type: string
- in: header
name: Prefer
schema:
type: string
description: Set `return=minimal` for HTTP 204 responses.
responses:
'200':
description: Rows deleted
content:
application/json:
schema:
type: object
properties:
data:
type: array
items:
type: object
'204':
description: 'Delete succeeded with Prefer: return=minimal'
'400':
description: Missing filters
'500':
description: Internal error
/pipelines:
post:
summary: Run a config-driven pipeline (source → transform → sink)
description: Executes a pipeline with optional prebuilt reference and overrides. Supports source/sink client overrides, optional column aliasing, and dry-run mode.
parameters:
- in: header
name: X-Athena-Client
required: true
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
pipeline:
type: string
description: Prebuilt pipeline name from config/pipelines.yaml
source:
type: object
properties:
table_name:
type: string
view_name:
type: string
columns:
type: array
items:
type: string
conditions:
type: array
items:
type: object
properties:
eq_column:
type: string
eq_value:
type: string
limit:
type: integer
client:
type: string
description: Optional source step client override (falls back to X-Athena-Client).
transform:
type: object
properties:
group_by:
type: string
time_granularity:
type: string
enum:
- day
- hour
- minute
aggregation_column:
type: string
aggregation_strategy:
type: string
enum:
- cumulative_sum
aggregation_dedup:
type: boolean
column_aliases:
type: object
additionalProperties:
type: string
description: Optional map of source column names to sink aliases.
sink:
type: object
properties:
table_name:
type: string
client:
type: string
description: Optional sink step client override (falls back to X-Athena-Client).
dry_run:
type: boolean
description: When true, fetch+transform runs but sink inserts are skipped.
responses:
'200':
description: Pipeline run result
content:
application/json:
schema:
type: object
properties:
data:
type: array
description: Inserted rows (or preview rows for dry runs)
rows_fetched:
type: integer
rows_inserted:
type: integer
would_insert:
type: integer
nullable: true
dry_run:
type: boolean
source_client:
type: string
sink_client:
type: string
errors:
type: array
'400':
description: Bad request (e.g. missing X-Athena-Client or unknown pipeline)
'500':
description: Internal error
/pipelines/simulate:
post:
summary: Simulate a pipeline without writing
description: Executes fetch+transform only and returns a dry-run preview payload.
parameters:
- in: header
name: X-Athena-Client
required: true
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
type: object
description: Same schema as POST /pipelines.
responses:
'200':
description: Dry-run pipeline result
'400':
description: Bad request
'500':
description: Internal error
/pipelines/templates:
get:
summary: List available pipeline templates
description: Returns named pipeline templates loaded from config/pipelines.yaml.
parameters:
- in: header
name: X-Athena-Client
required: true
schema:
type: string
responses:
'200':
description: Template list
content:
application/json:
schema:
type: object
properties:
templates:
type: array
items:
type: object
properties:
name:
type: string
source_table:
type: string
sink_table:
type: string
has_transform:
type: boolean
'500':
description: Internal error
/admin/api-keys:
get:
summary: List all API keys
description: Requires the static admin key stored in `ATHENA_KEY_12`.
parameters:
- $ref: '#/components/parameters/AdminApiKeyHeader'
responses:
'200':
description: Paginated API key records
content:
application/json:
schema:
type: object
properties:
api_keys:
type: array
items:
$ref: '#/components/schemas/ApiKeyRecord'
'500':
$ref: '#/components/responses/DefaultServerError5xx'
post:
summary: Create a new API key
parameters:
- $ref: '#/components/parameters/AdminApiKeyHeader'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateApiKeyRequest'
responses:
'201':
description: API key created
content:
application/json:
schema:
$ref: '#/components/schemas/CreateApiKeyResponse'
'409':
description: Duplicate public_id
'500':
$ref: '#/components/responses/DefaultServerError5xx'
/admin/api-keys/{id}:
patch:
summary: Update an existing API key
parameters:
- $ref: '#/components/parameters/AdminApiKeyHeader'
- $ref: '#/components/parameters/ApiKeyIdParam'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/UpdateApiKeyRequest'
responses:
'200':
description: API key updated
content:
application/json:
schema:
type: object
properties:
record:
$ref: '#/components/schemas/ApiKeyRecord'
'404':
description: API key not found
'500':
$ref: '#/components/responses/DefaultServerError5xx'
delete:
summary: Delete an API key
parameters:
- $ref: '#/components/parameters/AdminApiKeyHeader'
- $ref: '#/components/parameters/ApiKeyIdParam'
responses:
'200':
description: API key removed
content:
application/json:
schema:
type: object
properties:
id:
type: string
format: uuid
'404':
description: API key not found
'500':
$ref: '#/components/responses/DefaultServerError5xx'
/admin/api-key-rights:
get:
summary: List API key rights
parameters:
- $ref: '#/components/parameters/AdminApiKeyHeader'
responses:
'200':
description: Available rights
content:
application/json:
schema:
type: object
properties:
rights:
type: array
items:
$ref: '#/components/schemas/ApiKeyRightRecord'
'500':
$ref: '#/components/responses/DefaultServerError5xx'
post:
summary: Create a new API key right
parameters:
- $ref: '#/components/parameters/AdminApiKeyHeader'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/ApiKeyRightRequest'
responses:
'201':
description: API key right created
content:
application/json:
schema:
type: object
properties:
right:
$ref: '#/components/schemas/ApiKeyRightRecord'
'500':
$ref: '#/components/responses/DefaultServerError5xx'
/admin/api-key-rights/{id}:
patch:
summary: Update an API key right
parameters:
- $ref: '#/components/parameters/AdminApiKeyHeader'
- $ref: '#/components/parameters/ApiKeyIdParam'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/ApiKeyRightRequest'
responses:
'200':
description: API key right updated
content:
application/json:
schema:
type: object
properties:
right:
$ref: '#/components/schemas/ApiKeyRightRecord'
'404':
description: Right not found
'500':
$ref: '#/components/responses/DefaultServerError5xx'
delete:
summary: Delete an API key right
parameters:
- $ref: '#/components/parameters/AdminApiKeyHeader'
- $ref: '#/components/parameters/ApiKeyIdParam'
responses:
'200':
description: API key right removed
content:
application/json:
schema:
type: object
properties:
id:
type: string
format: uuid
'404':
description: Right not found
'500':
$ref: '#/components/responses/DefaultServerError5xx'
/admin/api-key-config:
get:
summary: Get global API key enforcement configuration
parameters:
- $ref: '#/components/parameters/AdminApiKeyHeader'
responses:
'200':
description: Global+per-client config
content:
application/json:
schema:
$ref: '#/components/schemas/ApiKeyConfigResponse'
'500':
$ref: '#/components/responses/DefaultServerError5xx'
put:
summary: Toggle global API key enforcement
parameters:
- $ref: '#/components/parameters/AdminApiKeyHeader'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/ApiKeyConfigRequest'
responses:
'200':
description: Updated global config
content:
application/json:
schema:
$ref: '#/components/schemas/ApiKeyConfigResponse'
'500':
$ref: '#/components/responses/DefaultServerError5xx'
/admin/api-key-clients:
get:
summary: List per-client API key enforcement overrides
parameters:
- $ref: '#/components/parameters/AdminApiKeyHeader'
responses:
'200':
description: Client configs
content:
application/json:
schema:
$ref: '#/components/schemas/ApiKeyClientListResponse'
'500':
$ref: '#/components/responses/DefaultServerError5xx'
/admin/api-key-clients/{client_name}:
put:
summary: Update or insert a client's enforcement override
parameters:
- $ref: '#/components/parameters/AdminApiKeyHeader'
- name: client_name
in: path
required: true
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/ApiKeyClientConfigRequest'
responses:
'200':
description: Client config upserted
content:
application/json:
schema:
type: object
properties:
client:
$ref: '#/components/schemas/ApiKeyClientConfig'
'500':
$ref: '#/components/responses/DefaultServerError5xx'
delete:
summary: Remove a client's enforcement override
parameters:
- $ref: '#/components/parameters/AdminApiKeyHeader'
- name: client_name
in: path
required: true
schema:
type: string
responses:
'200':
description: Client override deleted
content:
application/json:
schema:
type: object
properties:
client_name:
type: string
'404':
description: Client config not found
'500':
$ref: '#/components/responses/DefaultServerError5xx'
/admin/clients:
get:
summary: List Athena clients from the database-backed catalog
parameters:
- $ref: '#/components/parameters/AdminApiKeyHeader'
responses:
'200':
description: Athena clients and their runtime state
content:
application/json:
schema:
$ref: '#/components/schemas/AdminClientsResponse'
'500':
$ref: '#/components/responses/DefaultServerError5xx'
post:
summary: Create a database-backed Athena client
parameters:
- $ref: '#/components/parameters/AdminApiKeyHeader'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/SaveAthenaClientRequest'
responses:
'201':
description: Athena client created
content:
application/json:
schema:
$ref: '#/components/schemas/AdminClientResponse'
'500':
$ref: '#/components/responses/DefaultServerError5xx'
/admin/clients/{client_name}:
patch:
summary: Update an Athena client
parameters:
- $ref: '#/components/parameters/AdminApiKeyHeader'
- name: client_name
in: path
required: true
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/SaveAthenaClientRequest'
responses:
'200':
description: Athena client updated
content:
application/json:
schema:
$ref: '#/components/schemas/AdminClientResponse'
'500':
$ref: '#/components/responses/DefaultServerError5xx'
delete:
summary: Soft-delete an Athena client
parameters:
- $ref: '#/components/parameters/AdminApiKeyHeader'
- name: client_name
in: path
required: true
schema:
type: string
responses:
'200':
description: Athena client deleted
content:
application/json:
schema:
$ref: '#/components/schemas/AdminClientResponse'
'404':
description: Athena client not found
'500':
$ref: '#/components/responses/DefaultServerError5xx'
/admin/clients/{client_name}/freeze:
put:
summary: Freeze or unfreeze an Athena client
parameters:
- $ref: '#/components/parameters/AdminApiKeyHeader'
- name: client_name
in: path
required: true
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/FreezeAthenaClientRequest'
responses:
'200':
description: Athena client freeze state updated
content:
application/json:
schema:
$ref: '#/components/schemas/AdminClientResponse'
'404':
description: Athena client not found
'500':
$ref: '#/components/responses/DefaultServerError5xx'
/admin/clients/statistics:
get:
summary: List Athena client statistics
parameters:
- $ref: '#/components/parameters/AdminApiKeyHeader'
responses:
'200':
description: Aggregated request and operation statistics
content:
application/json:
schema:
$ref: '#/components/schemas/ClientStatisticsListResponse'
'500':
$ref: '#/components/responses/DefaultServerError5xx'
/admin/clients/statistics/refresh:
post:
summary: Rebuild Athena client statistics from gateway logs
parameters:
- $ref: '#/components/parameters/AdminApiKeyHeader'
responses:
'200':
description: Statistics refreshed
content:
application/json:
schema:
$ref: '#/components/schemas/ClientStatisticsListResponse'
'500':
$ref: '#/components/responses/DefaultServerError5xx'
/admin/clients/{client_name}/statistics:
get:
summary: Inspect Athena client statistics and touched tables
parameters:
- $ref: '#/components/parameters/AdminApiKeyHeader'
- name: client_name
in: path
required: true
schema:
type: string
responses:
'200':
description: Per-client statistics
content:
application/json:
schema:
$ref: '#/components/schemas/ClientStatisticsDetailResponse'
'404':
description: Client statistics not found
'500':
$ref: '#/components/responses/DefaultServerError5xx'
/admin/vacuum-health:
get:
summary: List latest vacuum health snapshot per Postgres client
description: |
Returns the most recent `vacuum_health_snapshots` row per `client_name` stored in the logging database
(populated by the background vacuum health collector). Requires the static admin key (`ATHENA_KEY_12`).
parameters:
- $ref: '#/components/parameters/AdminApiKeyHeader'
responses:
'200':
description: Latest vacuum health summaries
content:
application/json:
schema:
$ref: '#/components/schemas/VacuumHealthListResponse'
'500':
$ref: '#/components/responses/DefaultServerError5xx'
/admin/vacuum-health/{client_name}:
get:
summary: Latest vacuum health snapshot and per-table stats for one client
description: |
Returns the latest snapshot for `client_name` plus all `vacuum_health_table_stats` rows for that snapshot.
Requires the static admin key (`ATHENA_KEY_12`).
parameters:
- $ref: '#/components/parameters/AdminApiKeyHeader'
- name: client_name
in: path
required: true
schema:
type: string
responses:
'200':
description: Snapshot and per-table statistics
content:
application/json:
schema:
$ref: '#/components/schemas/VacuumHealthDetailResponse'
'404':
description: No vacuum health snapshots for this client
'500':
$ref: '#/components/responses/DefaultServerError5xx'
/admin/backups:
post:
summary: Create a database backup and upload to S3
description: |
Uses `pg_dump` against the provided `client_name`, uploads the archive to the configured S3 bucket, and stores an optional `label` in the object metadata.
Requires the static admin key (`ATHENA_KEY_12`) and S3 configuration (`ATHENA_BACKUP_S3_BUCKET`, `ATHENA_BACKUP_S3_PREFIX`, and credentials).
parameters:
- $ref: '#/components/parameters/AdminApiKeyHeader'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateBackupRequest'
responses:
'200':
description: Backup created and uploaded
content:
application/json:
schema:
type: object
properties:
key:
type: string
client_name:
type: string
label:
type: string
nullable: true
'400':
description: Missing or unknown client_name
'401':
description: Invalid admin API key
'503':
description: S3 not configured
get:
summary: List available backups in S3
description: Returns S3 backup objects filtered by optional `client_name` prefix, newest first.
parameters:
- $ref: '#/components/parameters/AdminApiKeyHeader'
- name: client_name
in: query
required: false
schema:
type: string
description: When set, only list backups for this client.
responses:
'200':
description: Backup listing
content:
application/json:
schema:
type: object
properties:
backups:
type: array
items:
$ref: '#/components/schemas/BackupObject'
'401':
description: Invalid admin API key
'503':
description: S3 not configured
/admin/backups/{key}/restore:
post:
summary: Restore a database backup from S3
description: |
Downloads the backup identified by the S3 object key, runs `pg_restore` into the target `client_name` Postgres pool, and returns the key plus client.
parameters:
- $ref: '#/components/parameters/AdminApiKeyHeader'
- name: key
in: path
required: true
schema:
type: string
description: S3 object key for the backup (URL-encoded, may contain slashes).
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/RestoreBackupRequest'
responses:
'200':
description: Restore completed
content:
application/json:
schema:
type: object
properties:
key:
type: string
client_name:
type: string
'400':
description: Missing key or client_name
'401':
description: Invalid admin API key
'503':
description: S3 not configured
/admin/backups/{key}/download:
get:
summary: Download a backup archive from S3
description: |
Streams the raw `application/gzip` backup bytes with a `Content-Disposition: attachment` filename.
parameters:
- $ref: '#/components/parameters/AdminApiKeyHeader'
- name: key
in: path
required: true
description: S3 object key for the backup (URL-encoded, may contain slashes).
schema:
type: string
responses:
'200':
description: Backup archive
content:
application/gzip:
schema:
type: string
format: binary
'400':
description: Missing backup key
'401':
description: Invalid admin API key
'404':
description: Backup not found
'503':
description: S3 not configured
/admin/backups/{key}:
delete:
summary: Delete a backup from S3
parameters:
- $ref: '#/components/parameters/AdminApiKeyHeader'
- name: key
in: path
required: true
description: S3 object key for the backup (URL-encoded, may contain slashes).
schema:
type: string
responses:
'200':
description: Backup deleted
content:
application/json:
schema:
type: object
properties:
key:
type: string
'400':
description: Missing backup key
'401':
description: Invalid admin API key
'404':
description: Backup not found
'503':
description: S3 not configured
/admin/provision:
post:
summary: Provision a Postgres database with the Athena schema
description: |
Runs the bundled provisioning SQL against either a direct `uri` or a registered `client_name`.
When `register` is true and `uri` is provided, the client is added to the runtime catalog after provisioning.
parameters:
- $ref: '#/components/parameters/AdminApiKeyHeader'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/ProvisionRequest'
responses:
'200':
description: Provisioning completed
content:
application/json:
schema:
type: object
properties:
statements_executed:
type: integer
client:
type: string
registered:
type: string
nullable: true
tables:
type: array
items:
type: string
'400':
description: Ambiguous or missing target
'401':
description: Invalid admin API key
'503':
description: Target client unavailable
/admin/provision/status:
get:
summary: Check whether a client database is provisioned
parameters:
- $ref: '#/components/parameters/AdminApiKeyHeader'
- name: client_name
in: query
required: true
schema:
type: string
description: Registered client to check.
responses:
'200':
description: Provisioning status
content:
application/json:
schema:
$ref: '#/components/schemas/ProvisionStatusResponse'
'401':
description: Invalid admin API key
'503':
description: Client unavailable
/admin/provision/instances:
post:
summary: Spin up a local Docker-backed Postgres instance
description: |
Creates (or reuses) a managed local Postgres container, optionally provisions Athena schema,
and can register the resulting connection in runtime and/or catalog client registries.
parameters:
- $ref: '#/components/parameters/AdminApiKeyHeader'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/SpinUpInstanceRequest'
responses:
'200':
description: Postgres instance is ready
'400':
description: Invalid spin-up payload
'401':
description: Invalid admin API key
'409':
description: Container conflict (already exists and reuse disabled)
'503':
description: Docker unavailable
/admin/provision/instances/{container_name}:
get:
summary: Inspect a local managed Postgres instance
parameters:
- $ref: '#/components/parameters/AdminApiKeyHeader'
- name: container_name
in: path
required: true
schema:
type: string
- name: client_name
in: query
required: false
schema:
type: string
responses:
'200':
description: Instance status loaded
'401':
description: Invalid admin API key
'404':
description: Instance not found
'503':
description: Docker unavailable
delete:
summary: Delete a local managed Postgres instance
parameters:
- $ref: '#/components/parameters/AdminApiKeyHeader'
- name: container_name
in: path
required: true
schema:
type: string
requestBody:
required: false
content:
application/json:
schema:
$ref: '#/components/schemas/DeleteInstanceRequest'
responses:
'200':
description: Instance deleted
'401':
description: Invalid admin API key
'503':
description: Docker unavailable
/admin/provision/providers/neon:
post:
summary: Provision/register a Neon Postgres database
parameters:
- $ref: '#/components/parameters/AdminApiKeyHeader'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/NeonProviderProvisionRequest'
responses:
'200':
description: Neon database provisioned
'400':
description: Invalid provider payload
'401':
description: Invalid admin API key
'503':
description: Provider unavailable
/admin/provision/providers/railway:
post:
summary: Provision/register a Railway Postgres database
parameters:
- $ref: '#/components/parameters/AdminApiKeyHeader'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/RailwayProviderProvisionRequest'
responses:
'200':
description: Railway database provisioned
'400':
description: Invalid provider payload
'401':
description: Invalid admin API key
'503':
description: Provider unavailable
/admin/provision/providers/render:
post:
summary: Provision/register a Render Postgres database
parameters:
- $ref: '#/components/parameters/AdminApiKeyHeader'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/RenderProviderProvisionRequest'
responses:
'200':
description: Render database provisioned
'400':
description: Invalid provider payload
'401':
description: Invalid admin API key
'503':
description: Provider unavailable
/api/v2/supabase/ssl_enforcement:
post:
summary: Toggle Supabase SSL enforcement for a project
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
enabled:
type: boolean
description: Set to true to enable SSL enforcement, false to disable
access_token:
type: string
description: Optional override for SUPABASE_ACCESS_TOKEN
project_ref:
type: string
description: Optional override for PROJECT_REF
required:
- enabled
responses:
'200':
description: SSL enforcement status returned
content:
application/json:
schema:
type: object
properties:
status:
type: string
example: success
message:
type: string
data:
type: object
properties:
currentConfig:
type: object
properties:
database:
type: boolean
appliedSuccessfully:
type: boolean
'400':
description: Missing credentials or bad payload
'500':
description: Supabase API error
/router/registry:
get:
summary: List Athena router registry entries
responses:
'200':
description: An array of router registry objects
content:
application/json:
schema:
type: array
items:
type: object
'500':
description: Failed to load router registry entries
/metrics:
get:
summary: Prometheus metrics endpoint
description: Exposes Prometheus text metrics including uptime, request counters, management mutation counters, cluster probe gauges, and 24-hour aggregates.
responses:
'200':
description: Metrics payload
content:
text/plain:
schema:
type: string
example: |
# TYPE athena_uptime_seconds gauge
athena_uptime_seconds 123.0
'500':
$ref: '#/components/responses/DefaultServerError5xx'
/registry:
get:
summary: List API registry entries
parameters:
- in: header
name: Cache-Control
schema:
type: string
description: Set to `no-cache` to skip the cached response.
responses:
'200':
description: API registry rows from Supabase
content:
application/json:
schema:
type: array
items:
type: object
'500':
description: Failed to list API registry entries
/registry/{api_registry_id}:
get:
summary: Lookup an API registry entry by ID
parameters:
- in: path
name: api_registry_id
required: true
schema:
type: string
description: Row identifier from the Supabase table
- in: header
name: Cache-Control
schema:
type: string
description: Set to `no-cache` to bypass the cached entry.
responses:
'200':
description: Matching registry entry (wrapped in an array)
content:
application/json:
schema:
type: array
items:
type: object
'500':
description: Failed to fetch the registry entry
/schema/clients:
get:
summary: List configured Postgres clients
description: Protected by the static admin key (`ATHENA_KEY_12`).
parameters:
- $ref: '#/components/parameters/AdminApiKeyHeader'
responses:
'200':
description: A JSON object containing a clients array
content:
application/json:
schema:
$ref: '#/components/schemas/ClientsResponse'
'500':
$ref: '#/components/responses/DefaultServerError5xx'
/clients:
get:
summary: List Athena/Postgres clients (admin)
description: Same response as `/schema/clients`, but exposed without the `schema` prefix.
parameters:
- $ref: '#/components/parameters/AdminApiKeyHeader'
responses:
'200':
description: Configured clients
content:
application/json:
schema:
$ref: '#/components/schemas/ClientsResponse'
'500':
$ref: '#/components/responses/DefaultServerError5xx'
/schema/tables:
get:
summary: List tables for the selected Postgres client
parameters:
- in: header
name: X-Athena-Client
required: true
schema:
type: string
description: Selects which Postgres pool provides the tables.
responses:
'200':
description: Table schema metadata
content:
application/json:
schema:
type: object
properties:
tables:
type: array
items:
type: object
properties:
table_schema:
type: string
table_name:
type: string
'400':
description: Missing or unknown X-Athena-Client
'500':
description: Failed to query information_schema.tables
/schema/columns:
get:
summary: Describe columns for a given table
parameters:
- in: header
name: X-Athena-Client
required: true
schema:
type: string
- in: header
name: X-API-Key
required: false
schema:
type: string
description: Optional API key (also apikey, X-Athena-Key, Authorization Bearer)
- in: query
name: table_name
required: true
schema:
type: string
description: Postgres table name to describe
- in: query
name: table_schema
required: false
schema:
type: string
description: Optional schema name; when provided, restricts columns to this schema
responses:
'200':
description: Column metadata
content:
application/json:
schema:
type: object
properties:
columns:
type: array
items:
type: object
properties:
column_name:
type: string
data_type:
type: string
nullable: true
column_default:
type: string
nullable: true
is_nullable:
type: string
nullable: true
'400':
description: Missing header or invalid table_name
'500':
description: Failed to fetch column metadata
/schema/migrations:
get:
summary: List schema migrations (Supabase-style)
description: Returns migration records from supabase_migrations.schema_migrations. If the table does not exist, returns an empty array with a message instead of an error.
parameters:
- in: header
name: X-Athena-Client
required: true
schema:
type: string
responses:
'200':
description: Migrations list or empty with message when table absent
content:
application/json:
schema:
type: object
properties:
migrations:
type: array
items:
type: object
properties:
version:
type: string
nullable: true
name:
type: string
nullable: true
message:
type: string
description: Present when migrations table does not exist
'400':
description: Missing X-Athena-Client
'500':
description: Other database error
/openapi.yaml:
get:
summary: Download the embedded OpenAPI YAML
responses:
'200':
description: OpenAPI spec fixture served by the API
content:
application/yaml:
schema:
type: string
'500':
description: Failed to read openapi.yaml
/openapi-wss.yaml:
get:
summary: Download the embedded WebSocket OpenAPI YAML
responses:
'200':
description: WebSocket OpenAPI spec fixture served by the API
content:
application/yaml:
schema:
type: string
'500':
description: Failed to read openapi-wss.yaml
/wss/info:
get:
summary: Read the WebSocket gateway contract
description: Returns rollout metadata and the current WebSocket gateway message contract.
responses:
'200':
description: WebSocket gateway contract metadata
content:
application/json:
schema:
type: object
properties:
status:
type: string
example: success
message:
type: string
example: Athena WebSocket gateway scaffold
data:
type: object
properties:
transport:
type: string
example: wss
path:
type: string
example: /wss/gateway
state:
type: string
example: scaffolded
notes:
type: array
items:
type: string
actions:
type: array
items:
type: string
example:
- gateway.fetch
- gateway.insert
- gateway.update
- gateway.delete
- gateway.query
'500':
$ref: '#/components/responses/DefaultServerError5xx'
/docs:
get:
summary: Redirect to the hosted Athena docs
responses:
'308':
description: Permanent redirect to https://xylex.group/docs/athena
headers:
Location:
schema:
type: string
format: uri
'500':
$ref: '#/components/responses/DefaultServerError5xx'
components:
responses:
DefaultServerError5xx:
description: Internal server error (or other 5xx). Standard envelope with status, message, and error.
content:
application/json:
schema:
type: object
required:
- status
- message
- error
properties:
status:
type: string
example: error
message:
type: string
description: Human-readable summary
error:
type: string
description: Error detail
parameters:
AdminApiKeyHeader:
name: apikey
in: header
description: |
The static admin key configured as `ATHENA_KEY_12`. Authorization headers (`Bearer <key>`), `X-API-Key`, `X-Athena-Key`, or `?api_key=` are also accepted.
required: true
schema:
type: string
ApiKeyIdParam:
name: id
in: path
required: true
description: UUID that identifies an API key or API key right (`api_keys_id`, `api_key_rights_id`).
schema:
type: string
format: uuid
schemas:
ApiKeyRecord:
type: object
properties:
id:
type: string
format: uuid
public_id:
type: string
name:
type: string
description:
type: string
nullable: true
client_name:
type: string
nullable: true
expires_at:
type: string
format: date-time
nullable: true
is_active:
type: boolean
last_used_at:
type: string
format: date-time
nullable: true
created_at:
type: string
format: date-time
updated_at:
type: string
format: date-time
rights:
type: array
items:
type: string
CreateApiKeyRequest:
type: object
properties:
name:
type: string
description:
type: string
nullable: true
client_name:
type: string
nullable: true
expires_at:
type: string
format: date-time
nullable: true
rights:
type: array
items:
type: string
required:
- name
UpdateApiKeyRequest:
type: object
properties:
name:
type: string
description:
type: string
nullable: true
client_name:
type: string
nullable: true
expires_at:
type: string
format: date-time
nullable: true
is_active:
type: boolean
rights:
type: array
items:
type: string
CreateApiKeyResponse:
type: object
properties:
api_key:
type: string
example: ath_abcdefghijklmnop.secret
record:
$ref: '#/components/schemas/ApiKeyRecord'
ApiKeyRightRequest:
type: object
properties:
name:
type: string
description:
type: string
nullable: true
required:
- name
ApiKeyRightRecord:
type: object
properties:
id:
type: string
format: uuid
name:
type: string
description:
type: string
nullable: true
created_at:
type: string
format: date-time
updated_at:
type: string
format: date-time
ApiKeyConfigRequest:
type: object
properties:
enforce_api_keys:
type: boolean
required:
- enforce_api_keys
ApiKeyGlobalConfig:
type: object
properties:
enforce_api_keys:
type: boolean
updated_at:
type: string
format: date-time
ApiKeyClientConfig:
type: object
properties:
client_name:
type: string
enforce_api_keys:
type: boolean
created_at:
type: string
format: date-time
updated_at:
type: string
format: date-time
ApiKeyConfigResponse:
type: object
properties:
global:
$ref: '#/components/schemas/ApiKeyGlobalConfig'
clients:
type: array
items:
$ref: '#/components/schemas/ApiKeyClientConfig'
ApiKeyClientConfigRequest:
type: object
properties:
enforce_api_keys:
type: boolean
required:
- enforce_api_keys
ApiKeyClientListResponse:
type: object
properties:
clients:
type: array
items:
$ref: '#/components/schemas/ApiKeyClientConfig'
ClientsResponse:
type: object
properties:
clients:
type: array
items:
type: string
AthenaClientRecord:
type: object
properties:
id:
type: string
format: uuid
client_name:
type: string
description:
type: string
nullable: true
pg_uri:
type: string
nullable: true
pg_uri_env_var:
type: string
nullable: true
config_uri_template:
type: string
nullable: true
source:
type: string
is_active:
type: boolean
is_frozen:
type: boolean
last_synced_from_config_at:
type: string
format: date-time
nullable: true
last_seen_at:
type: string
format: date-time
nullable: true
metadata:
type: object
additionalProperties: true
created_at:
type: string
format: date-time
updated_at:
type: string
format: date-time
deleted_at:
type: string
format: date-time
nullable: true
RuntimeAthenaClient:
type: object
properties:
client_name:
type: string
source:
type: string
description:
type: string
nullable: true
pg_uri:
type: string
nullable: true
pg_uri_env_var:
type: string
nullable: true
config_uri_template:
type: string
nullable: true
is_active:
type: boolean
is_frozen:
type: boolean
pool_connected:
type: boolean
SaveAthenaClientRequest:
type: object
properties:
client_name:
type: string
description:
type: string
nullable: true
pg_uri:
type: string
nullable: true
pg_uri_env_var:
type: string
nullable: true
is_active:
type: boolean
FreezeAthenaClientRequest:
type: object
properties:
is_frozen:
type: boolean
required:
- is_frozen
AdminClientResponse:
type: object
properties:
client:
$ref: '#/components/schemas/AthenaClientRecord'
AdminClientsResponse:
type: object
properties:
clients:
type: array
items:
$ref: '#/components/schemas/AthenaClientRecord'
runtime:
type: array
items:
$ref: '#/components/schemas/RuntimeAthenaClient'
ClientStatisticsRecord:
type: object
properties:
client_name:
type: string
total_requests:
type: integer
successful_requests:
type: integer
failed_requests:
type: integer
total_cached_requests:
type: integer
total_operations:
type: integer
last_request_at:
type: string
format: date-time
nullable: true
last_operation_at:
type: string
format: date-time
nullable: true
updated_at:
type: string
format: date-time
ClientTableStatisticsRecord:
type: object
properties:
client_name:
type: string
table_name:
type: string
operation:
type: string
total_operations:
type: integer
error_operations:
type: integer
last_operation_at:
type: string
format: date-time
nullable: true
updated_at:
type: string
format: date-time
ClientStatisticsListResponse:
type: object
properties:
statistics:
type: array
items:
$ref: '#/components/schemas/ClientStatisticsRecord'
ClientStatisticsDetailResponse:
type: object
properties:
statistics:
$ref: '#/components/schemas/ClientStatisticsRecord'
tables:
type: array
items:
$ref: '#/components/schemas/ClientTableStatisticsRecord'
VacuumHealthSnapshotRecord:
type: object
properties:
id:
type: integer
format: int64
recorded_at:
type: string
format: date-time
client_name:
type: string
host:
type: string
nullable: true
instance_id:
type: string
format: uuid
nullable: true
total_dead_rows:
type: integer
format: int64
tables_with_bloat:
type: integer
xid_freeze_risk:
type: integer
tables_needing_vacuum:
type: integer
freeze_max_age:
type: integer
format: int64
nullable: true
collection_error:
type: string
nullable: true
VacuumHealthTableStatRecord:
type: object
properties:
id:
type: integer
format: int64
snapshot_id:
type: integer
format: int64
schemaname:
type: string
relname:
type: string
n_dead_tup:
type: integer
format: int64
n_live_tup:
type: integer
format: int64
dead_pct:
type: number
nullable: true
last_vacuum:
type: string
format: date-time
nullable: true
last_autovacuum:
type: string
format: date-time
nullable: true
xid_age:
type: integer
format: int64
nullable: true
xid_age_pct_of_freeze_max:
type: number
nullable: true
VacuumHealthListResponse:
type: object
description: Returned in the success envelope `data` field from GET /admin/vacuum-health
properties:
snapshots:
type: array
items:
$ref: '#/components/schemas/VacuumHealthSnapshotRecord'
VacuumHealthDetailResponse:
type: object
description: Returned in the success envelope `data` field from GET /admin/vacuum-health/{client_name}
properties:
snapshot:
$ref: '#/components/schemas/VacuumHealthSnapshotRecord'
tables:
type: array
items:
$ref: '#/components/schemas/VacuumHealthTableStatRecord'
ManagementColumnRequest:
type: object
properties:
name:
type: string
data_type:
type: string
nullable:
type: boolean
default: true
default_expression:
type: string
nullable: true
required:
- name
- data_type
CreateTableRequest:
type: object
properties:
schema_name:
type: string
default: public
table_name:
type: string
columns:
type: array
items:
$ref: '#/components/schemas/ManagementColumnRequest'
if_not_exists:
type: boolean
description: Accepted for compatibility but ignored; Athena still returns 409 when the table exists.
required:
- table_name
EditTableRequest:
type: object
properties:
schema_name:
type: string
default: public
operations:
type: array
items:
oneOf:
- type: object
properties:
type:
type: string
enum:
- add_column
column:
$ref: '#/components/schemas/ManagementColumnRequest'
required:
- type
- column
- type: object
properties:
type:
type: string
enum:
- rename_column
from:
type: string
to:
type: string
required:
- type
- from
- to
- type: object
properties:
type:
type: string
enum:
- set_default
column_name:
type: string
default_expression:
type: string
required:
- type
- column_name
- default_expression
- type: object
properties:
type:
type: string
enum:
- drop_default
column_name:
type: string
required:
- type
- column_name
- type: object
properties:
type:
type: string
enum:
- set_not_null
column_name:
type: string
required:
- type
- column_name
- type: object
properties:
type:
type: string
enum:
- drop_not_null
column_name:
type: string
required:
- type
- column_name
required:
- operations
DropTableRequest:
type: object
properties:
schema_name:
type: string
default: public
cascade:
type: boolean
default: false
DropColumnRequest:
type: object
properties:
schema_name:
type: string
default: public
cascade:
type: boolean
default: false
CreateIndexRequest:
type: object
properties:
schema_name:
type: string
default: public
table_name:
type: string
index_name:
type: string
nullable: true
columns:
type: array
items:
type: string
unique:
type: boolean
default: false
method:
type: string
default: btree
required:
- table_name
- columns
DropIndexRequest:
type: object
properties:
schema_name:
type: string
default: public
ManagementCapabilities:
type: object
properties:
backend:
type: string
retention_mutation_supported:
type: boolean
replication_mutation_supported:
type: boolean
supported_operations:
type: array
items:
type: string
required_rights:
type: array
items:
type: object
properties:
operation:
type: string
required_right:
type: string
allowed_index_methods:
type: array
items:
type: string
allowed_column_data_types:
type: array
items:
type: string
ManagementCapabilitiesEnvelope:
type: object
properties:
status:
type: string
message:
type: string
data:
$ref: '#/components/schemas/ManagementCapabilities'
ClusterMirrorHealth:
type: object
properties:
url:
type: string
format: uri
status:
type: string
enum:
- online
- offline
latency_ms:
type: number
nullable: true
download_bytes_per_sec:
type: number
nullable: true
cargo_toml_version:
type: string
nullable: true
message:
type: string
nullable: true
ClusterHealthResponse:
type: object
properties:
message:
type: string
version:
type: string
athena_api:
type: string
athena_deadpool:
type: string
athena_scylladb:
type: string
cargo_toml_version:
type: string
mirrors:
type: array
items:
$ref: '#/components/schemas/ClusterMirrorHealth'
CreateBackupRequest:
type: object
properties:
client_name:
type: string
description: Logical client whose Postgres URI will be dumped.
label:
type: string
nullable: true
description: Optional human-readable label stored in S3 object metadata.
required:
- client_name
RestoreBackupRequest:
type: object
properties:
client_name:
type: string
description: Logical client whose Postgres URI is the restore target.
required:
- client_name
BackupObject:
type: object
properties:
id:
type: string
description: Backup identifier derived from the S3 object key.
key:
type: string
description: Full S3 object key.
client_name:
type: string
label:
type: string
nullable: true
size_bytes:
type: integer
format: int64
created_at:
type: string
description: Timestamp string from S3 metadata.
ProvisionRequest:
type: object
properties:
uri:
type: string
format: uri
description: Direct Postgres URI to provision (mutually exclusive with client_name).
client_name:
type: string
description: Registered client whose URI will be used (mutually exclusive with uri).
register:
type: boolean
default: false
description: When true and uri is provided, register the client in the runtime catalog.
register_name:
type: string
nullable: true
description: Optional client name when registering (defaults to "provisioned").
ProvisionStatusResponse:
type: object
properties:
client_name:
type: string
provisioned:
type: boolean
present_tables:
type: array
items:
type: string
missing_tables:
type: array
items:
type: string
SpinUpInstanceRequest:
type: object
properties:
client_name:
type: string
container_name:
type: string
nullable: true
image:
type: string
nullable: true
host:
type: string
nullable: true
host_port:
type: integer
format: int32
nullable: true
db_name:
type: string
nullable: true
username:
type: string
nullable: true
password:
type: string
nullable: true
startup_timeout_secs:
type: integer
format: int64
nullable: true
reuse_existing:
type: boolean
default: false
provision_schema:
type: boolean
default: true
register_runtime:
type: boolean
default: true
register_catalog:
type: boolean
default: true
required:
- client_name
DeleteInstanceRequest:
type: object
properties:
client_name:
type: string
nullable: true
remove_runtime_client:
type: boolean
default: true
remove_catalog_client:
type: boolean
default: true
NeonProviderProvisionRequest:
type: object
properties:
client_name:
type: string
description:
type: string
nullable: true
connection_uri:
type: string
nullable: true
api_key:
type: string
nullable: true
project_id:
type: string
nullable: true
branch_id:
type: string
nullable: true
database_name:
type: string
nullable: true
role_name:
type: string
nullable: true
endpoint_id:
type: string
nullable: true
api_base_url:
type: string
nullable: true
create_project_if_missing:
type: boolean
default: false
project_name:
type: string
nullable: true
project_create_payload:
type: object
nullable: true
provision_schema:
type: boolean
default: true
register_runtime:
type: boolean
default: true
register_catalog:
type: boolean
default: true
required:
- client_name
RailwayProviderProvisionRequest:
type: object
properties:
client_name:
type: string
description:
type: string
nullable: true
connection_uri:
type: string
nullable: true
api_key:
type: string
nullable: true
project_id:
type: string
nullable: true
environment_id:
type: string
nullable: true
service_id:
type: string
nullable: true
plugin_id:
type: string
nullable: true
graphql_url:
type: string
nullable: true
create_project_if_missing:
type: boolean
default: false
project_name:
type: string
nullable: true
project_create_input:
type: object
nullable: true
create_service_if_missing:
type: boolean
default: false
service_name:
type: string
nullable: true
service_create_input:
type: object
nullable: true
create_plugin_if_missing:
type: boolean
default: false
plugin_name:
type: string
nullable: true
plugin_create_input:
type: object
nullable: true
provision_schema:
type: boolean
default: true
register_runtime:
type: boolean
default: true
register_catalog:
type: boolean
default: true
required:
- client_name
RenderProviderProvisionRequest:
type: object
properties:
client_name:
type: string
description:
type: string
nullable: true
connection_uri:
type: string
nullable: true
api_key:
type: string
nullable: true
service_id:
type: string
nullable: true
owner_id:
type: string
nullable: true
api_base_url:
type: string
nullable: true
create_service_if_missing:
type: boolean
default: false
service_name:
type: string
nullable: true
service_create_payload:
type: object
nullable: true
plan:
type: string
nullable: true
region:
type: string
nullable: true
postgres_version:
type: string
nullable: true
disk_size_gb:
type: integer
format: int32
nullable: true
provision_schema:
type: boolean
default: true
register_runtime:
type: boolean
default: true
register_catalog:
type: boolean
default: true
required:
- client_name