API Reference

Complete Iceberg REST Catalog API documentation.

Table of contents

  1. Base URL
  2. Authentication
  3. Configuration
    1. Get Configuration
  4. Namespaces
    1. List Namespaces
    2. Create Namespace
    3. Get Namespace
    4. Update Namespace Properties
    5. Drop Namespace
  5. Tables
    1. List Tables
    2. Create Table
    3. Load Table
    4. Update Table (Commit)
    5. Table Exists
    6. Drop Table
    7. Rename Table
    8. Register Table
  6. Views
    1. List Views
    2. Create View
    3. Load View
    4. Drop View
    5. View Exists
    6. Commit View
    7. Rename View
  7. Transactions
    1. Commit Transaction
  8. Metrics
    1. Report Metrics
  9. Search
    1. Search Catalog
  10. Credentials
    1. Load Credentials
  11. Health & Metrics
    1. Health Check
    2. Readiness Check
    3. Prometheus Metrics
  12. Error Responses
    1. Error Format
    2. Error Codes
  13. Rate Limiting
  14. Pagination
  15. Request Headers
  16. Next Steps

Base URL

https://your-rustberg-host:8181

Authentication

All endpoints require authentication via Authorization header:

Authorization: Bearer rustberg_your_api_key_here

Or JWT token:

Authorization: Bearer eyJhbGciOiJSUzI1NiIs...

Configuration

Get Configuration

Returns catalog configuration and defaults.

GET /v1/config

Response:

{
  "defaults": {},
  "overrides": {}
}

Namespaces

List Namespaces

GET /v1/namespaces

Query Parameters:

Parameter Type Description
parent string Parent namespace (optional)
pageToken string Pagination token
pageSize integer Results per page (default: 100)

Response:

{
  "namespaces": [
    ["analytics"],
    ["raw", "events"]
  ],
  "next-page-token": "abc123"
}

Create Namespace

POST /v1/namespaces

Request:

{
  "namespace": ["analytics"],
  "properties": {
    "owner": "data-team"
  }
}

Response: 200 OK

{
  "namespace": ["analytics"],
  "properties": {
    "owner": "data-team"
  }
}

Get Namespace

GET /v1/namespaces/{namespace}

Response:

{
  "namespace": ["analytics"],
  "properties": {
    "owner": "data-team"
  }
}

Update Namespace Properties

POST /v1/namespaces/{namespace}/properties

Request:

{
  "updates": {
    "description": "Analytics tables"
  },
  "removals": ["deprecated-key"]
}

Drop Namespace

DELETE /v1/namespaces/{namespace}

Response: 204 No Content


Tables

List Tables

GET /v1/namespaces/{namespace}/tables

Response:

{
  "identifiers": [
    {
      "namespace": ["analytics"],
      "name": "events"
    },
    {
      "namespace": ["analytics"],
      "name": "users"
    }
  ]
}

Create Table

POST /v1/namespaces/{namespace}/tables

Request:

{
  "name": "events",
  "location": "s3://my-bucket/analytics/events",
  "schema": {
    "type": "struct",
    "schema-id": 0,
    "fields": [
      {
        "id": 1,
        "name": "id",
        "required": true,
        "type": "long"
      },
      {
        "id": 2,
        "name": "event_type",
        "required": true,
        "type": "string"
      },
      {
        "id": 3,
        "name": "timestamp",
        "required": true,
        "type": "timestamptz"
      }
    ]
  },
  "partition-spec": {
    "spec-id": 0,
    "fields": [
      {
        "source-id": 3,
        "field-id": 1000,
        "name": "ts_day",
        "transform": "day"
      }
    ]
  },
  "properties": {
    "write.format.default": "parquet"
  }
}

Response: 200 OK with table metadata

Load Table

GET /v1/namespaces/{namespace}/tables/{table}

Response:

{
  "metadata-location": "s3://bucket/metadata/v1.metadata.json",
  "metadata": {
    "format-version": 2,
    "table-uuid": "abc123",
    "location": "s3://bucket/table",
    "schema": {...},
    "partition-spec": {...},
    "properties": {...}
  },
  "config": {
    "s3.access-key-id": "AKIA...",
    "s3.secret-access-key": "..."
  }
}

Update Table (Commit)

POST /v1/namespaces/{namespace}/tables/{table}

Request:

{
  "identifier": {
    "namespace": ["analytics"],
    "name": "events"
  },
  "requirements": [
    {
      "type": "assert-current-schema-id",
      "current-schema-id": 0
    }
  ],
  "updates": [
    {
      "action": "add-schema",
      "schema": {
        "type": "struct",
        "fields": [...]
      }
    },
    {
      "action": "set-current-schema",
      "schema-id": 1
    }
  ]
}

Table Exists

HEAD /v1/namespaces/{namespace}/tables/{table}

Response: 204 No Content (exists) or 404 Not Found

Drop Table

DELETE /v1/namespaces/{namespace}/tables/{table}

Query Parameters:

Parameter Type Description
purgeRequested boolean Also delete data files

Response: 204 No Content

Rename Table

POST /v1/tables/rename

Request:

{
  "source": {
    "namespace": ["analytics"],
    "name": "events_old"
  },
  "destination": {
    "namespace": ["analytics"],
    "name": "events_new"
  }
}

Register Table

Register an existing table from a metadata file location.

POST /v1/namespaces/{namespace}/register

Request:

{
  "name": "imported_events",
  "metadata-location": "s3://bucket/metadata/v1.metadata.json"
}

Views

List Views

GET /v1/namespaces/{namespace}/views

Create View

POST /v1/namespaces/{namespace}/views

Load View

GET /v1/namespaces/{namespace}/views/{view}

Drop View

DELETE /v1/namespaces/{namespace}/views/{view}

View Exists

HEAD /v1/namespaces/{namespace}/views/{view}

Commit View

POST /v1/namespaces/{namespace}/views/{view}

Rename View

POST /v1/views/rename

Transactions

Commit Transaction

Atomically commit changes to multiple tables.

POST /v1/transactions/commit

Request:

{
  "table-changes": [
    {
      "identifier": {
        "namespace": ["analytics"],
        "name": "events"
      },
      "requirements": [...],
      "updates": [...]
    },
    {
      "identifier": {
        "namespace": ["analytics"],
        "name": "events_summary"
      },
      "requirements": [...],
      "updates": [...]
    }
  ]
}

Response: 204 No Content on success


Metrics

Report Metrics

Report table operation metrics from clients.

POST /v1/namespaces/{namespace}/tables/{table}/metrics

Request:

{
  "table-name": "analytics.events",
  "snapshot-id": 1234567890,
  "filter": "timestamp > '2026-01-01'",
  "schema-id": 0,
  "projected-field-ids": [1, 2, 3],
  "projected-field-names": ["id", "event_type", "timestamp"],
  "metrics": {
    "total-planning-duration": {"unit": "nanos", "value": 123456},
    "total-data-manifests": {"unit": "count", "value": 5},
    "total-files-size": {"unit": "bytes", "value": 1073741824}
  }
}

Search Catalog

Search for tables and views across namespaces.

GET /v1/search

Query Parameters:

Parameter Type Description
query string Search query
type string table or view (optional)

Response:

{
  "results": [
    {
      "type": "table",
      "identifier": {
        "namespace": ["analytics"],
        "name": "events"
      }
    }
  ]
}

Credentials

Load Credentials

Get temporary credentials for accessing table storage.

GET /v1/namespaces/{namespace}/tables/{table}/credentials

Response:

{
  "s3.access-key-id": "ASIATEMP...",
  "s3.secret-access-key": "...",
  "s3.session-token": "...",
  "expiration-ms": 3600000
}

Health & Metrics

Health Check

GET /health

Response: 200 OK

{
  "status": "healthy"
}

Readiness Check

GET /ready

Response: 200 OK when ready to serve traffic

Prometheus Metrics

GET /metrics

Response: Prometheus text format

# HELP rustberg_requests_total Total HTTP requests
# TYPE rustberg_requests_total counter
rustberg_requests_total{method="GET",status="200"} 1234

Error Responses

Error Format

{
  "error": {
    "message": "Table not found",
    "type": "NoSuchTableException",
    "code": 404
  }
}

Error Codes

Code Type Description
400 BadRequestException Invalid request format
401 NotAuthenticatedException Missing/invalid auth
403 NotAuthorizedException Insufficient permissions
404 NoSuchNamespaceException Namespace not found
404 NoSuchTableException Table not found
409 AlreadyExistsException Resource already exists
409 CommitFailedException Optimistic concurrency failure
422 ValidationException Business rule violation
429 TooManyRequestsException Rate limited
500 ServiceException Internal error

Rate Limiting

When rate limited, response includes:

HTTP/1.1 429 Too Many Requests
Retry-After: 60
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1706313600

Pagination

List endpoints support cursor-based pagination:

GET /v1/namespaces?pageSize=50&pageToken=abc123

Response:

{
  "namespaces": [...],
  "next-page-token": "def456"
}

When next-page-token is null or absent, no more results.


Request Headers

Header Required Description
Authorization Yes Bearer token
Content-Type Yes (POST) application/json
X-Request-Id No Request correlation ID
X-Iceberg-Access-Delegation No vended-credentials

Next Steps