Catalog over HTTP

Use the Catalog API to read and manage database, schema, table, and view definitions. Reads return complete definitions. Writes replace the selected resource, so the safe editing sequence is read, edit, preview, apply, and read back.

For a terminal workflow that exports definitions and saves reviewable plans, use the CLI Catalog guide.

Resources

Use your workspace endpoint and API key. Resource names in paths are percent-encoded individually.

ResourcePathMethods
Catalog/v1/catalogGET, PUT
Database/v1/catalog/databases/{database}GET, PUT, DELETE
Schema/v1/catalog/databases/{database}/schemas/{schema}GET, PUT, DELETE
Table/v1/catalog/databases/{database}/schemas/{schema}/tables/{table}GET, PUT, DELETE
View/v1/catalog/databases/{database}/schemas/{schema}/views/{view}GET, PUT, DELETE

GET returns the definition as the JSON response body, with its version in the ETag header. Reads are not paginated. Prefer the narrowest resource you need: read one table for its schema, or one schema to discover its tables and views.

PUT creates or replaces a resource using a complete JSON definition. Omitted fields and children are cleared; this is not a partial update. DELETE removes the selected resource. Mutation responses contain before, after, and destructive, with an ETag response header. A missing resource is represented by null in before or after.

Read a table definition

This example uses the events table from the quickstart, in the scopedb database and public schema. It requires curl and, for the edit below, jq.

export SCOPEDB_TABLE_URL="$SCOPEDB_ENDPOINT/v1/catalog/databases/scopedb/schemas/public/tables/events"

curl --fail-with-body --silent --show-error \
  "$SCOPEDB_TABLE_URL" \
  -H "Authorization: Bearer $SCOPEDB_API_KEY" \
  --dump-header catalog.headers \
  --output table.json

Inspect table.json. The definition includes the table's name and columns, whose entries include name and data_type, along with its other settings. Preserve all fields, including fields your client does not recognize, when editing an existing definition.

Preview a change

Change only the comment and keep the ETag, including its quotes:

jq '.comment = "Checkout events"' table.json > desired-table.json
catalog_etag=$(awk 'tolower($1) == "etag:" {gsub("\r", ""); print $2}' catalog.headers)
test -n "$catalog_etag" && \
curl --fail-with-body --silent --show-error -X PUT \
  "$SCOPEDB_TABLE_URL?dry_run=true" \
  -H "Authorization: Bearer $SCOPEDB_API_KEY" \
  -H "Content-Type: application/json" \
  -H "If-Match: $catalog_etag" \
  --data-binary @desired-table.json \
  --dump-header plan.headers \
  --output plan.json

Read plan.json and compare before with after. This comment-only change should have destructive: false. dry_run=true previews the change without committing it.

Apply the reviewed definition

After reviewing the plan, send the same desired-table.json with the preview's ETag and without dry_run=true:

plan_etag=$(awk 'tolower($1) == "etag:" {gsub("\r", ""); print $2}' plan.headers)
test -n "$plan_etag" && \
curl --fail-with-body --silent --show-error -X PUT \
  "$SCOPEDB_TABLE_URL" \
  -H "Authorization: Bearer $SCOPEDB_API_KEY" \
  -H "Content-Type: application/json" \
  -H "If-Match: $plan_etag" \
  --data-binary @desired-table.json

The response's after definition contains the new comment. Read the table again to verify the stored value:

curl --fail-with-body --silent --show-error \
  "$SCOPEDB_TABLE_URL" \
  -H "Authorization: Bearer $SCOPEDB_API_KEY"

Handle conflicts and interrupted writes

Control or responseMeaning
If-Match: <etag>Apply only against the catalog version you reviewed. Keep the value unchanged, including its quotes.
HTTP 412, catalog_version_mismatchThe catalog changed. Read the current definition and preview a new plan; do not bypass the check.
HTTP 409, catalog_destructive_changeThe change can remove data or definitions. Inspect the preview before explicitly allowing it.
allow_destructive=truePermit a destructive mutation. This is an explicit opt-in on PUT or DELETE, separate from dry_run.
catalog_commit_outcome_unknownA commit may have completed. Read the resource to establish its current state before planning another write.

Both query flags accept true or false and default to false. A dry run can show a destructive plan without committing it. Do not apply such a plan until you understand what it removes.

Treat an interrupted mutation as potentially committed. Never automatically replay a Catalog write just because the connection timed out. A dry run does not commit, but its ETag may become stale before application. See HTTP errors and retries.