Iceberg REST API
The Iceberg REST API is the Apache Iceberg REST catalog protocol, served by the Iceberg REST service. Spark, Trino, Flink, PyIceberg and other Iceberg engines use it to list, create, load and commit tables and views. This reference covers the operations the service implements, from the Apache Iceberg 1.11.0 specification.
Base URL
Every path in this reference is relative to https://{iceberg_host}/iceberg, where
{iceberg_host} is the host the service is published on; see HTTPS.
Engines take this address as the catalog URI.
The service serves the Iceberg catalogs of one metalake. Each Gravitino catalog is a separate
Iceberg REST catalog, selected by the {prefix} in the path. A client finds the prefix by calling
GET /v1/config with the catalog name as warehouse; the response returns it in defaults.prefix.
A client that names no warehouse gets the service's default catalog.
curl -sS -H "Authorization: Bearer $TOKEN" \
"https://{iceberg_host}/iceberg/v1/config?warehouse={catalog}"
Authentication
Every call needs credentials:
- A bearer token issued by the identity provider the server is configured for.
- A user name and password of a local user, sent as HTTP basic credentials.
Each call is checked against the caller's roles in the metalake, and a call the roles do not allow returns HTTP 403; see Privileges.
Credential vending
A client that sends X-Iceberg-Access-Delegation: vended-credentials when it loads or creates a
table receives temporary storage credentials scoped to that table, and an endpoint to refresh them.
vended-credentials is the only delegation mode the service supports. See
Credential vending.
Example
The script signs in, reads the catalog's configuration, then creates a namespace and a table, loads
the table with vended credentials, and cleans up. It needs curl and jq. Set the variables at the
top, and pick one way to sign in.
#!/usr/bin/env bash
set -euo pipefail
ICEBERG_URI="https://{iceberg_host}/iceberg"
CATALOG="{catalog}"
NAMESPACE="irc_example"
TABLE="orders"
PASSWORD="${PASSWORD:?set PASSWORD first}"
# 1. Sign in. A local user sends basic credentials on every call:
AUTH="Authorization: Basic $(printf '%s:%s' "{user}" "$PASSWORD" | base64)"
# Or request a token from your identity provider with client credentials:
# TOKEN=$(curl -sS -X POST "{token_endpoint}" \
# -d grant_type=client_credentials -d client_id="{client_id}" \
# -d client_secret="$CLIENT_SECRET" -d scope="{scope}" | jq -r .access_token)
# AUTH="Authorization: Bearer $TOKEN"
call() { curl -sS --fail-with-body -H "$AUTH" -H "Content-Type: application/json" "$@"; }
# 2. Read the catalog's configuration and the prefix for later calls.
PREFIX=$(call "$ICEBERG_URI/v1/config?warehouse=$CATALOG" | jq -r .defaults.prefix)
BASE="$ICEBERG_URI/v1/$PREFIX"
# 3. Create a namespace and list the catalog's namespaces.
call -X POST "$BASE/namespaces" -d "{\"namespace\": [\"$NAMESPACE\"]}" | jq .
call "$BASE/namespaces" | jq .namespaces
# 4. Create a table.
call -X POST "$BASE/namespaces/$NAMESPACE/tables" -d "{
\"name\": \"$TABLE\",
\"schema\": {\"type\": \"struct\", \"schema-id\": 0, \"fields\": [
{\"id\": 1, \"name\": \"order_id\", \"type\": \"long\", \"required\": true},
{\"id\": 2, \"name\": \"amount\", \"type\": \"decimal(10,2)\", \"required\": false}
]}
}" | jq -r '.["metadata-location"]'
# 5. List the namespace's tables, then load the table with vended storage credentials.
call "$BASE/namespaces/$NAMESPACE/tables" | jq .identifiers
call -H "X-Iceberg-Access-Delegation: vended-credentials" \
"$BASE/namespaces/$NAMESPACE/tables/$TABLE" | jq '{location: .metadata.location, credentials: (.config | keys)}'
# 6. Refresh the table's storage credentials.
call "$BASE/namespaces/$NAMESPACE/tables/$TABLE/credentials" | jq '.["storage-credentials"][].prefix'
# 7. Clean up: drop the table and its data, then the namespace.
call -X DELETE "$BASE/namespaces/$NAMESPACE/tables/$TABLE?purgeRequested=true"
call -X DELETE "$BASE/namespaces/$NAMESPACE"
The caller needs USE_CATALOG, CREATE_SCHEMA and CREATE_TABLE on the catalog, and owns the
namespace and table it creates; see Privileges. A catalog with a table encryption policy
that requires a key rejects a create that names none, with HTTP 400 and the reason KEY_REQUIRED. A namespace with more than one level is
written with its levels separated by %1F in the path, as in sales%1Feu.
Errors
A failed call returns an HTTP error status and an Iceberg error body:
{
"error": {
"message": "Namespace does not exist: sales",
"type": "NoSuchNamespaceException",
"code": 404
}
}
Operations not served
The service does not implement these operations from the Iceberg specification: POST /v1/oauth/tokens,
GET and DELETE /v1/{prefix}/namespaces/{namespace}/tables/{table}/plan/{plan-id},
POST /v1/{prefix}/namespaces/{namespace}/tables/{table}/tasks,
POST /v1/{prefix}/namespaces/{namespace}/tables/{table}/sign,
POST /v1/{prefix}/transactions/commit and POST /v1/{prefix}/namespaces/{namespace}/register-view.
GET /v1/config lists the operations the service supports in its endpoints field.
Authentication
- HTTP: Bearer Auth
- HTTP: Basic Auth
A token issued by the identity provider the server is configured for.
Security Scheme Type: | http |
|---|---|
HTTP Authorization Scheme: | bearer |
The user name and password of a local user.
Security Scheme Type: | http |
|---|---|
HTTP Authorization Scheme: | basic |
License
Apache 2.0