---
title: "Read a connection's synced warehouse catalog."
method: GET
path: "/v1/connections/{id}/catalog"
tags: ["connections"]
---

# Read a connection's synced warehouse catalog.

`GET /v1/connections/{id}/catalog`

## Request

- Base URL: `http://localhost:8080`
- URL: `http://localhost:8080/v1/connections/{id}/catalog`
- Auth: one of:
  - API key in cookie `dvt_session`
  - HTTP bearer

Returns the persisted catalog (databases/schemas/tables/views, with columns
on tables/views) for a connection with `catalogSyncEnabled: true` (A3,
DVT-1810). This is a pure read of what `jobs.CatalogSyncJob` has already
persisted — it never drives the warehouse itself (use `POST .../catalog/sync`
to request a fresh pass). Metadata only (names/types/comments) — never data
rows (ADR-0011 amendment).

With no query params, returns the full tree ordered parent-before-child.
`query` and/or `kind` switch to a bounded (200-row), name-prefix search
instead of the full tree. Requires the `data:query` scope (same floor as
`POST /v1/data/describe`) — an API key without it is rejected even if the
connection itself is accessible.

Returns an empty array (not a 404) for a connection that has never been
synced, or has `catalogSyncEnabled: false`.

## Query parameters

- `query` string
- `kind` 'database' | 'schema' | 'table' | 'view'

## Response `200`

The connection's synced catalog (possibly empty).

- CatalogObjectCollection
  - `data` CatalogObject[], required
    - `id` string, uuid, required
    - `connectionId` string, uuid, required
    - `orgId` string, uuid, required
    - `parentId` string, uuid, nullable: Absent/null for a top-level node (a database, or a top-level schema).
    - `kind` 'database' | 'schema' | 'table' | 'view', required
    - `name` string, required
    - `comment` string, nullable: Warehouse object comment, if any (may be PII per ADR-0011). Truncated at 4000 characters.
    - `syncedAt` string, date-time, required: When this node was last written by a sync pass.
    - `columns` CatalogColumn[]: Populated for kind=table/view only.
      - `name` string, required
      - `ordinal` integer, required: 1-based position, assigned in name-sorted order (the engine's columns-bulk response is name-keyed, not warehouse-ordinal).
      - `dataType` string, required
      - `nullable` boolean, required
      - `comment` string, nullable: Warehouse column comment, if any (may be PII per ADR-0011). Truncated at 4000 characters.
  - `meta` Meta, required: Response metadata.
    - `requestId` string, required: Correlates with the X-Request-Id header.
    - `total` integer: Item count, present on collection responses.
    - `nextCursor` string, nullable: Opaque keyset-pagination cursor, present on paginated responses (e.g. GET /v1/dashboards) when more rows exist beyond this page. Pass it back as the `cursor` query param to fetch the next page; absent or null on the last page.
    - `roleResolveDegraded` boolean: Snowflake mode only (DVT-2260), on GET /v1/dashboards: present and true when the caller's live Snowflake role resolution failed or was unavailable — role-shared dashboards may be missing from this page. Omitted (not merely false) whenever resolution succeeded or the role-share arm does not apply (off snowflake mode, an org admin/owner, or off the ingress listener).

## Other responses

- `401`: Missing, invalid, or expired session.
- `403`: The caller's role does not permit this action.
- `404`: Resource does not exist.

---

[API](https://skmtc.dev/dvt/apis/dvt-rest-api.md) · [All operations](https://skmtc.dev/dvt/apis/dvt-rest-api/llms.txt) · [OpenAPI document](https://skmtc.dev/dvt/apis/dvt-rest-api/revisions/00016f504165?raw)
