Skip to main content

View API

View endpoints provide operations for creating, reading, updating, and deleting Iceberg views through the REST Catalog API.

List Views

List all views in a namespace.
GET /v1/{prefix}/namespaces/{namespace}/views

Path Parameters

prefix
string
required
Optional prefix for multi-tenant deployments
namespace
string
required
Namespace identifier (multi-part namespaces use %1F separator)

Query Parameters

pageToken
string
Pagination token from a previous response
pageSize
integer
Maximum number of views to return

Response

identifiers
array
required
List of view identifiers
next-page-token
string
Token for next page of results

Example

curl -X GET "https://catalog.example.com/v1/production/namespaces/analytics/views" \
  -H "Authorization: Bearer <token>"
{
  "identifiers": [
    {
      "namespace": ["analytics"],
      "name": "monthly_revenue"
    },
    {
      "namespace": ["analytics"],
      "name": "top_customers"
    }
  ]
}

Create View

Create a new view in the specified namespace.
POST /v1/{prefix}/namespaces/{namespace}/views

Path Parameters

prefix
string
required
Optional prefix for multi-tenant deployments
namespace
string
required
Namespace identifier

Request Body

name
string
required
View name
location
string
View location. If not provided, a location will be generated.
schema
object
required
View schema definition
view-version
object
required
Initial view version with query definition
properties
object
View properties

Response

metadata-location
string
required
Location of view metadata file
metadata
object
required
Complete view metadata
config
object
Additional configuration for the view

Example

curl -X POST "https://catalog.example.com/v1/production/namespaces/analytics/views" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "monthly_revenue",
    "schema": {
      "type": "struct",
      "fields": [
        {"id": 1, "name": "month", "type": "date", "required": true},
        {"id": 2, "name": "revenue", "type": "decimal(10,2)", "required": true}
      ]
    },
    "view-version": {
      "version-id": 1,
      "timestamp-ms": 1672531200000,
      "schema-id": 0,
      "default-namespace": ["analytics"],
      "summary": {"engine": "spark"},
      "representations": [
        {
          "type": "sql",
          "sql": "SELECT date_trunc(\'month\', sale_date) as month, SUM(amount) as revenue FROM sales GROUP BY 1",
          "dialect": "spark"
        }
      ]
    },
    "properties": {
      "comment": "Monthly revenue summary"
    }
  }'

Load View

Load view metadata from the catalog.
GET /v1/{prefix}/namespaces/{namespace}/views/{view}

Path Parameters

prefix
string
required
Optional prefix for multi-tenant deployments
namespace
string
required
Namespace identifier
view
string
required
View name

Query Parameters

referenced-by
string
Comma-separated list of view identifiers referencing this view

Response

metadata-location
string
required
Location of view metadata file
metadata
object
required
Complete view metadata including schema, versions, and properties
config
object
Additional configuration and credentials for accessing the view

Example

curl -X GET "https://catalog.example.com/v1/production/namespaces/analytics/views/monthly_revenue" \
  -H "Authorization: Bearer <token>"
{
  "metadata-location": "s3://bucket/warehouse/analytics/monthly_revenue/metadata/v1.metadata.json",
  "metadata": {
    "view-uuid": "fa6506c3-7681-40c8-86dc-e36561f83385",
    "format-version": 1,
    "location": "s3://bucket/warehouse/analytics/monthly_revenue",
    "schemas": [
      {
        "schema-id": 0,
        "type": "struct",
        "fields": [
          {"id": 1, "name": "month", "type": "date", "required": true},
          {"id": 2, "name": "revenue", "type": "decimal(10,2)", "required": true}
        ]
      }
    ],
    "current-version-id": 1,
    "versions": [...],
    "version-log": [...],
    "properties": {
      "comment": "Monthly revenue summary"
    }
  }
}

Replace View

Update an existing view with a new version.
POST /v1/{prefix}/namespaces/{namespace}/views/{view}

Path Parameters

prefix
string
required
Optional prefix for multi-tenant deployments
namespace
string
required
Namespace identifier
view
string
required
View name

Headers

Idempotency-Key
string (uuid)
UUIDv7 for idempotent request handling

Request Body

requirements
array
Assertions that must be true before applying updates
updates
array
required
Changes to apply to view metadata

Response

metadata-location
string
required
Location of new metadata file
metadata
object
required
Updated view metadata

Example

curl -X POST "https://catalog.example.com/v1/production/namespaces/analytics/views/monthly_revenue" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "requirements": [
      {
        "type": "assert-view-uuid",
        "uuid": "fa6506c3-7681-40c8-86dc-e36561f83385"
      }
    ],
    "updates": [
      {
        "action": "add-view-version",
        "view-version": {
          "version-id": 2,
          "schema-id": 0,
          "timestamp-ms": 1672617600000,
          "representations": [
            {
              "type": "sql",
              "sql": "SELECT date_trunc(\'month\', sale_date) as month, SUM(amount) as revenue FROM sales WHERE region = \'US\' GROUP BY 1",
              "dialect": "spark"
            }
          ]
        }
      },
      {
        "action": "set-current-view-version",
        "version-id": 2
      }
    ]
  }'
View updates use requirements and updates similar to table commits. Requirements ensure the view hasn’t changed since it was last read.

Check View Exists

Check if a view exists without loading its metadata.
HEAD /v1/{prefix}/namespaces/{namespace}/views/{view}

Path Parameters

prefix
string
required
Optional prefix for multi-tenant deployments
namespace
string
required
Namespace identifier
view
string
required
View name

Response

No response body. Status code indicates existence.

Example

curl -I "https://catalog.example.com/v1/production/namespaces/analytics/views/monthly_revenue" \
  -H "Authorization: Bearer <token>"
Success:
HTTP/1.1 204 No Content
Not Found:
HTTP/1.1 404 Not Found

Drop View

Delete a view from the catalog.
DELETE /v1/{prefix}/namespaces/{namespace}/views/{view}

Path Parameters

prefix
string
required
Optional prefix for multi-tenant deployments
namespace
string
required
Namespace identifier
view
string
required
View name

Headers

Idempotency-Key
string (uuid)
UUIDv7 for idempotent request handling

Response

No response body on success.

Example

curl -X DELETE "https://catalog.example.com/v1/production/namespaces/analytics/views/monthly_revenue" \
  -H "Authorization: Bearer <token>"
Success:
HTTP/1.1 204 No Content

Rename View

Rename a view or move it to a different namespace.
POST /v1/{prefix}/views/rename

Path Parameters

prefix
string
required
Optional prefix for multi-tenant deployments

Headers

Idempotency-Key
string (uuid)
UUIDv7 for idempotent request handling

Request Body

source
object
required
Current view identifier
destination
object
required
New view identifier

Response

No response body on success.

Example

curl -X POST "https://catalog.example.com/v1/production/views/rename" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "source": {
      "namespace": ["analytics"],
      "name": "monthly_revenue"
    },
    "destination": {
      "namespace": ["analytics", "reports"],
      "name": "revenue_by_month"
    }
  }'
Moving views across namespaces is valid but not all servers support it. Check the 406 response if cross-namespace moves fail.

Register View

Register an existing view using its metadata file location.
POST /v1/{prefix}/namespaces/{namespace}/register-view

Path Parameters

prefix
string
required
Optional prefix for multi-tenant deployments
namespace
string
required
Namespace identifier

Headers

Idempotency-Key
string (uuid)
UUIDv7 for idempotent request handling

Request Body

name
string
required
View name to register
metadata-location
string
required
Location of existing view metadata file

Response

Same as Load View response.

Example

curl -X POST "https://catalog.example.com/v1/production/namespaces/analytics/register-view" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "imported_revenue",
    "metadata-location": "s3://external-bucket/views/revenue/metadata/v3.metadata.json"
  }'

Status Codes

Success

  • 200 OK - Request successful with response body
  • 204 No Content - Request successful without response body

Client Errors

  • 400 Bad Request - Invalid request format
  • 401 Unauthorized - Authentication required
  • 403 Forbidden - Not authorized
  • 404 Not Found - View or namespace does not exist
  • 406 Not Acceptable - Operation not supported
  • 409 Conflict - View already exists or commit requirements failed
  • 419 Authentication Timeout - Authentication expired

Server Errors

  • 500 Internal Server Error - Commit state unknown
  • 502 Bad Gateway - Gateway error, commit state unknown
  • 503 Service Unavailable - Service temporarily unavailable
  • 504 Gateway Timeout - Timeout, commit state unknown

View Versions

Views support versioning to track changes over time:
  • Each update creates a new view version
  • Versions contain SQL representations and metadata
  • The current version determines the view’s behavior
  • Version history is maintained in metadata

View Version Structure

{
  "version-id": 1,
  "timestamp-ms": 1672531200000,
  "schema-id": 0,
  "summary": {"engine": "spark"},
  "default-namespace": ["analytics"],
  "representations": [
    {
      "type": "sql",
      "sql": "SELECT ...",
      "dialect": "spark"
    }
  ]
}

Common Patterns

Create View with Multiple Representations

curl -X POST ".../namespaces/analytics/views" \
  -d '{
    "name": "revenue_view",
    "schema": {...},
    "view-version": {
      "representations": [
        {
          "type": "sql",
          "sql": "SELECT date, SUM(amount) FROM sales GROUP BY date",
          "dialect": "spark"
        },
        {
          "type": "sql",
          "sql": "SELECT date, SUM(amount) FROM sales GROUP BY 1",
          "dialect": "trino"
        }
      ]
    }
  }'

Update View Query

# Load current view
curl -X GET ".../views/revenue_view"
# Note current version: 1, uuid: abc-123

# Create new version
curl -X POST ".../views/revenue_view" \
  -d '{
    "requirements": [
      {"type": "assert-view-uuid", "uuid": "abc-123"}
    ],
    "updates": [
      {
        "action": "add-view-version",
        "view-version": {
          "version-id": 2,
          "representations": [
            {"type": "sql", "sql": "<updated query>", "dialect": "spark"}
          ]
        }
      },
      {"action": "set-current-view-version", "version-id": 2}
    ]
  }'

View References

When loading a view that references other views or tables:
curl -X GET ".../views/quarterly_revenue?referenced-by=analytics%1Fannual_summary" \
  -H "Authorization: Bearer <token>"
This helps track view dependency chains for access control and lineage.

Best Practices

  1. Version management: Keep view version history manageable
  2. Multiple dialects: Provide SQL representations for different engines
  3. Schema evolution: Update schema when view output changes
  4. Dependencies: Track view dependencies using referenced-by
  5. Idempotency: Use idempotency keys for safe retries

Build docs developers (and LLMs) love