openapi: 3.0.1
info:
title: Estuary Flow Control Plane API
description: >-
Representative OpenAPI description of the Estuary Flow control plane, a
Supabase deployment (Postgres + PostgREST + GoTrue) that exposes the
public-facing REST API for Estuary Flow. Clients authenticate with an
Authorization Bearer access token, which is obtained by exchanging a
long-lived refresh token through the generate_access_token RPC. Most
resources are PostgREST tables and RPCs; standard PostgREST query
conventions (select, filter operators like eq./gt., order, limit) apply
to the table endpoints. Publishing changes to the running data plane is an
asynchronous, draft-then-publish workflow. This document is a faithful
representative model and is not the vendor's canonical machine-readable
contract.
termsOfService: https://estuary.dev/terms/
contact:
name: Estuary Support
email: support@estuary.dev
version: '1.0'
servers:
- url: https://api.estuary.dev
description: Estuary Flow control plane (Supabase/PostgREST)
security:
- bearerAuth: []
paths:
/rpc/generate_access_token:
post:
operationId: generateAccessToken
tags:
- Auth
summary: Exchange a refresh token for a short-lived access token.
description: >-
PostgREST RPC that accepts a refresh_token id and secret and returns a
signed access_token used as the Authorization Bearer credential for all
other control-plane calls.
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/GenerateAccessTokenRequest'
responses:
'200':
description: A new access token.
content:
application/json:
schema:
$ref: '#/components/schemas/AccessToken'
'401':
description: Invalid or expired refresh token.
/refresh_tokens:
get:
operationId: listRefreshTokens
tags:
- Auth
summary: List refresh tokens for the authenticated user.
responses:
'200':
description: An array of refresh tokens.
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/RefreshToken'
post:
operationId: createRefreshToken
tags:
- Auth
summary: Create a new long-lived refresh token.
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/RefreshTokenCreate'
responses:
'201':
description: The created refresh token (secret returned once).
content:
application/json:
schema:
$ref: '#/components/schemas/RefreshToken'
/refresh_tokens/{id}:
delete:
operationId: deleteRefreshToken
tags:
- Auth
summary: Revoke a refresh token.
parameters:
- $ref: '#/components/parameters/RowId'
responses:
'204':
description: Revoked.
/user_grants:
get:
operationId: listUserGrants
tags:
- Auth
summary: List capability grants from users to catalog prefixes.
responses:
'200':
description: An array of user grants.
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Grant'
/role_grants:
get:
operationId: listRoleGrants
tags:
- Auth
summary: List capability grants between catalog prefixes (roles).
responses:
'200':
description: An array of role grants.
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Grant'
/live_specs:
get:
operationId: listLiveSpecs
tags:
- Captures
- Materializations
- Collections
summary: List live catalog specifications.
description: >-
Returns published, running catalog entities. Filter by catalog_name and
spec_type (capture, materialization, collection, test) using PostgREST
operators, e.g. spec_type=eq.capture.
parameters:
- name: catalog_name
in: query
schema:
type: string
description: PostgREST filter, e.g. like.acmeCo/%25
- name: spec_type
in: query
schema:
type: string
enum: [capture, materialization, collection, test]
description: PostgREST filter, e.g. eq.capture
- $ref: '#/components/parameters/Select'
responses:
'200':
description: An array of live specs.
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/LiveSpec'
/live_specs/{id}:
get:
operationId: getLiveSpec
tags:
- Captures
- Materializations
- Collections
summary: Get a single live specification.
parameters:
- $ref: '#/components/parameters/RowId'
responses:
'200':
description: The live spec.
content:
application/json:
schema:
$ref: '#/components/schemas/LiveSpec'
/live_spec_flows:
get:
operationId: listLiveSpecFlows
tags:
- Collections
summary: List data-flow edges between live specs (source to target lineage).
responses:
'200':
description: An array of live spec flow edges.
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/LiveSpecFlow'
/drafts:
get:
operationId: listDrafts
tags:
- Drafts
summary: List drafts owned by the user.
responses:
'200':
description: An array of drafts.
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Draft'
post:
operationId: createDraft
tags:
- Drafts
summary: Create a new empty draft.
requestBody:
required: false
content:
application/json:
schema:
$ref: '#/components/schemas/DraftCreate'
responses:
'201':
description: The created draft.
content:
application/json:
schema:
$ref: '#/components/schemas/Draft'
/drafts/{id}:
delete:
operationId: deleteDraft
tags:
- Drafts
summary: Delete a draft and its draft specs.
parameters:
- $ref: '#/components/parameters/RowId'
responses:
'204':
description: Deleted.
/draft_specs:
get:
operationId: listDraftSpecs
tags:
- Drafts
summary: List the specs staged within drafts.
parameters:
- name: draft_id
in: query
schema:
type: string
description: PostgREST filter, e.g. eq.<draft_id>
responses:
'200':
description: An array of draft specs.
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/DraftSpec'
post:
operationId: upsertDraftSpec
tags:
- Drafts
summary: Add or replace a capture, materialization, or collection spec in a draft.
description: >-
Upsert a draft_spec keyed by (draft_id, catalog_name). Send the
Prefer header 'resolution=merge-duplicates' to update in place.
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/DraftSpecUpsert'
responses:
'201':
description: The upserted draft spec.
content:
application/json:
schema:
$ref: '#/components/schemas/DraftSpec'
/publications:
get:
operationId: listPublications
tags:
- Publications
summary: List publication jobs and their status.
responses:
'200':
description: An array of publications.
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Publication'
post:
operationId: createPublication
tags:
- Publications
summary: Publish a draft into the running data plane.
description: >-
Enqueues an asynchronous publication of the given draft_id. Poll the
created publication row until job_status.type transitions from queued
to success or a failure state.
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/PublicationCreate'
responses:
'201':
description: The enqueued publication job.
content:
application/json:
schema:
$ref: '#/components/schemas/Publication'
/discovers:
post:
operationId: createDiscover
tags:
- Connectors
summary: Run connector schema discovery.
description: >-
Enqueues a discovery job against a connector image and endpoint config,
producing recommended bindings and collection schemas for a capture.
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/DiscoverCreate'
responses:
'201':
description: The enqueued discover job.
content:
application/json:
schema:
$ref: '#/components/schemas/Discover'
/connectors:
get:
operationId: listConnectors
tags:
- Connectors
summary: List available capture and materialization connectors.
responses:
'200':
description: An array of connectors.
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Connector'
/connector_tags:
get:
operationId: listConnectorTags
tags:
- Connectors
summary: List tagged image versions of connectors and their endpoint spec schemas.
responses:
'200':
description: An array of connector tags.
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/ConnectorTag'
/tenants:
get:
operationId: listTenants
tags:
- Tenants
summary: List tenants (billing/ownership prefixes) the user can access.
responses:
'200':
description: An array of tenants.
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Tenant'
/catalog_stats:
get:
operationId: listCatalogStats
tags:
- Tenants
summary: Read usage statistics (bytes and docs) per catalog entity and grain.
parameters:
- name: catalog_name
in: query
schema:
type: string
- name: grain
in: query
schema:
type: string
enum: [hourly, daily, monthly]
responses:
'200':
description: An array of catalog stat rows.
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/CatalogStat'
/rpc/billing_report_202308:
post:
operationId: billingReport
tags:
- Tenants
summary: Compute the monthly billing estimate for a tenant.
description: >-
RPC returning the data-movement GB, connector-instance line items, and
total for a tenant and billed month.
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/BillingReportRequest'
responses:
'200':
description: The billing report.
content:
application/json:
schema:
$ref: '#/components/schemas/BillingReport'
components:
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
description: >-
Access token obtained from /rpc/generate_access_token by exchanging a
refresh token. Sent as Authorization: Bearer <access_token>.
parameters:
RowId:
name: id
in: path
required: true
schema:
type: string
description: PostgREST row id filter, e.g. eq.<flowid>
Select:
name: select
in: query
schema:
type: string
description: PostgREST column/embed selection, e.g. select=id,catalog_name,spec_type
schemas:
GenerateAccessTokenRequest:
type: object
required:
- refresh_token
properties:
refresh_token:
type: object
properties:
id:
type: string
secret:
type: string
AccessToken:
type: object
properties:
access_token:
type: string
description: Short-lived signed JWT for Authorization Bearer.
refresh_token:
type: object
nullable: true
description: Optionally-rotated refresh token secret.
RefreshToken:
type: object
properties:
id:
type: string
detail:
type: string
nullable: true
secret:
type: string
nullable: true
description: Returned only at creation time.
created_at:
type: string
format: date-time
updated_at:
type: string
format: date-time
RefreshTokenCreate:
type: object
properties:
detail:
type: string
multi_use:
type: boolean
valid_for:
type: string
description: Postgres interval, e.g. '90 days'.
Grant:
type: object
properties:
id:
type: string
subject_role:
type: string
object_role:
type: string
capability:
type: string
enum: [read, write, admin]
LiveSpec:
type: object
properties:
id:
type: string
catalog_name:
type: string
spec_type:
type: string
enum: [capture, materialization, collection, test]
spec:
type: object
description: The full catalog spec document.
connector_image_name:
type: string
nullable: true
connector_image_tag:
type: string
nullable: true
reads_from:
type: array
items:
type: string
writes_to:
type: array
items:
type: string
last_pub_id:
type: string
updated_at:
type: string
format: date-time
LiveSpecFlow:
type: object
properties:
source_id:
type: string
target_id:
type: string
flow_type:
type: string
enum: [capture, materialization, collection, test]
Draft:
type: object
properties:
id:
type: string
detail:
type: string
nullable: true
created_at:
type: string
format: date-time
updated_at:
type: string
format: date-time
DraftCreate:
type: object
properties:
detail:
type: string
DraftSpec:
type: object
properties:
id:
type: string
draft_id:
type: string
catalog_name:
type: string
spec_type:
type: string
nullable: true
enum: [capture, materialization, collection, test]
spec:
type: object
nullable: true
description: The proposed spec document; null requests deletion on publish.
expect_pub_id:
type: string
nullable: true
DraftSpecUpsert:
type: object
required:
- draft_id
- catalog_name
properties:
draft_id:
type: string
catalog_name:
type: string
spec_type:
type: string
enum: [capture, materialization, collection, test]
spec:
type: object
Publication:
type: object
properties:
id:
type: string
draft_id:
type: string
dry_run:
type: boolean
job_status:
$ref: '#/components/schemas/JobStatus'
logs_token:
type: string
created_at:
type: string
format: date-time
PublicationCreate:
type: object
required:
- draft_id
properties:
draft_id:
type: string
dry_run:
type: boolean
default: false
detail:
type: string
Discover:
type: object
properties:
id:
type: string
connector_tag_id:
type: string
draft_id:
type: string
nullable: true
job_status:
$ref: '#/components/schemas/JobStatus'
logs_token:
type: string
DiscoverCreate:
type: object
required:
- connector_tag_id
- endpoint_config
- capture_name
properties:
connector_tag_id:
type: string
endpoint_config:
type: object
capture_name:
type: string
draft_id:
type: string
Connector:
type: object
properties:
id:
type: string
image_name:
type: string
title:
type: object
description: Localized title map.
short_description:
type: object
recommended:
type: boolean
ConnectorTag:
type: object
properties:
id:
type: string
connector_id:
type: string
image_tag:
type: string
protocol:
type: string
enum: [capture, materialize]
endpoint_spec_schema:
type: object
resource_spec_schema:
type: object
Tenant:
type: object
properties:
id:
type: string
tenant:
type: string
description: The tenant prefix, e.g. acmeCo/.
tasks_quota:
type: integer
collections_quota:
type: integer
created_at:
type: string
format: date-time
CatalogStat:
type: object
properties:
catalog_name:
type: string
grain:
type: string
enum: [hourly, daily, monthly]
ts:
type: string
format: date-time
bytes_written_by_me:
type: integer
bytes_read_by_me:
type: integer
docs_written_by_me:
type: integer
docs_read_by_me:
type: integer
BillingReportRequest:
type: object
required:
- billed_prefix
- billed_month
properties:
billed_prefix:
type: string
billed_month:
type: string
format: date
BillingReport:
type: object
properties:
billed_prefix:
type: string
billed_month:
type: string
line_items:
type: array
items:
type: object
properties:
description:
type: string
count:
type: number
rate:
type: number
subtotal:
type: number
total_processed_data_gb:
type: number
subtotal:
type: number
JobStatus:
type: object
properties:
type:
type: string
enum: [queued, buildFailed, testFailed, publishFailed, success, emptyDraft]