ReferenceAPI

Tables

Tables API methods, requests, and responses for RawTree Cloud and RawTree BYOC.

Tables

Reads require read permission. Inserts require write permission. Table creation, configuration, and deletion require admin permission.

GET /v1/tables

List tables in the selected database.

Use an API key, a permitted workload token, or a user bearer token. Database-role keys support only the operations listed in Authentication.

Request:

# List all tables in a database.
curl -X GET "https://api.rawtree.com/v1/tables?database=analytics" \
  -H "Authorization: Bearer $RAWTREE_API_KEY"

Expected response: HTTP 200.

{
  "tables": [
    {
      "name": "events",
      "created_at": "2026-11-09T10:00:00Z",
      "total_rows": 1,
      "total_bytes": 128
    }
  ]
}

Errors: 401. See API errors.

POST /v1/tables

Create a table. Requires admin permission.

{
  "name": "events",
  "sorting_key": "region, user.id",
  "settings": {
    "replacing_enable": true,
    "index_granularity": 4096
  }
}

sorting_key is optional. Omit it, or send an empty string, and the table picks a sorting key per part from the ingested data. The string contains SQL expressions in key order, separated by commas. A bare name such as user.id is read as a path into the ingested JSON.

settings is an optional object of engine setting names and JSON boolean, number, or string values. Strings are literal values, not SQL expressions. The engine validates setting names and values. Omitting settings or sending {} preserves the default creation behavior. Nonempty settings on a database with custom S3 return HTTP 400: Custom settings are not supported for custom S3.

Use an API key, a permitted workload token, or a user bearer token. Database-role keys support only the operations listed in Authentication.

Parameters:

FieldLocationTypeRequiredNotes
namebodystringYesTable name in the selected database. The table uses the database's customer-owned S3 storage when configured, then the cluster default.
sorting_keybodystring or nullNoOptional comma-separated SQL sorting expressions. Omit it, or send an empty string, to let the table pick a key per part from the ingested data.

Request:

# Create a table in the selected database.
curl -X POST "https://api.rawtree.com/v1/tables?database=analytics" \
  -H "Authorization: Bearer $RAWTREE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "events"
}'

Expected response: HTTP 201.

{
  "database": "analytics",
  "table": "events",
  "storage": {
    "type": "default"
  },
  "sorting_key": ""
}

Errors: 400, 401, 403, 409. See API errors.

GET /v1/tables/{table}

Describe a table. The response includes sorting_key, which is empty when the table picks a key per part. table.settings lists every explicitly configured setting, including settings supplied by the platform. Each entry has a name and a value in SQL syntax, with secrets masked by the engine:

{"name": "index_granularity", "value": "4096"}

Create and update responses also include this settings list. Unset engine defaults are not included, and the list does not identify who set each value.

Use an API key, a permitted workload token, or a user bearer token. Database-role keys support only the operations listed in Authentication.

Request:

# Describe columns of a table.
curl -X GET "https://api.rawtree.com/v1/tables/events?database=analytics" \
  -H "Authorization: Bearer $RAWTREE_API_KEY"

Expected response: HTTP 200.

{
  "table": {
    "name": "events",
    "created_at": "2026-11-09T10:00:00Z",
    "total_rows": 1,
    "total_bytes": 128,
    "columns": [
      {
        "name": "__raw_data",
        "type": "JSON"
      }
    ],
    "sorting_key": ""
  }
}

Errors: 400, 401. See API errors.

PATCH /v1/tables/{table}

Update a table's RawTree configuration. Requires admin permission. Only the fields you send are changed; omitted fields are left as they are.

{ "sorting_key": "timestamp" }

Functions and multiple expressions use the same string field. Commas inside function arguments remain part of that function:

{ "sorting_key": "ifNull(cityHash64(host, instanceId), 0)" }

To change table settings, send a nonempty settings object with the same value types accepted by POST:

{ "settings": { "max_parts_in_total": 100000 } }

Send sorting-key changes and settings changes in separate PATCH requests. Set the sorting key first when enabling replacement. Omitted settings retain their values; null is not a reset operation. Use Query API ALTER TABLE ... RESET SETTING ... to restore engine defaults. The engine decides which settings can be changed and which setting combinations are valid.

Bare column names inside functions resolve to fields in the ingested JSON. Use SQL identifier quotes for unusual column names, such as `user-agent`. Create, update, and describe responses return sorting_key as a string; an empty string indicates automatic sorting.

The new sorting key applies to newly inserted parts and wins later merges, so existing parts are re-sorted in the background rather than rewritten by the request. The key must contain at least one column or expression; a sorting key cannot be removed once set. The service checks expression syntax before sending the key to the engine. An unusable key, such as one that repeats a column, is answered with the engine's own error.

Use an API key, a permitted workload token, or a user bearer token. Database-role keys support only the operations listed in Authentication.

Parameters:

FieldLocationTypeRequiredNotes
sorting_keybodystring or nullNoComma-separated SQL expressions for the custom sorting key.

Request:

# Update a table's ClickHouse configuration.
curl -X PATCH "https://api.rawtree.com/v1/tables/events?database=analytics" \
  -H "Authorization: Bearer $RAWTREE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "sorting_key": "region, user.id"
}'

Expected response: HTTP 200.

{
  "database": "analytics",
  "table": "events",
  "sorting_key": "region, user.id"
}

Errors: 400, 401, 403. See API errors.

POST /v1/tables/{table}

Insert data. Send one JSON object or an array of JSON objects.

[{ "action": "click", "user": "alice" }]

Successful JSON body inserts without a transform return the database's native summary fields at the top level. Counters retain their string representation:

{
  "read_rows": "3",
  "read_bytes": "73",
  "written_rows": "3",
  "written_bytes": "73",
  "total_rows_to_read": "0",
  "result_rows": "3",
  "result_bytes": "73",
  "elapsed_ns": "74267625",
  "memory_usage": "1091943"
}

This example shows the native fields from a three-object insert; timing, memory, and byte counts depend on the request.

FieldMeaning
read_rowsRows processed from the input.
read_bytesInput-processing byte count reported by the database.
written_rowsReported insert row count. Deduplicated requests can report rows without adding new stored rows.
written_bytesReported insert byte count, not compressed storage size.
total_rows_to_readEstimated total input rows; zero can mean no estimate is available.
result_rowsExecution-result row count; for ordinary inserts this reflects insert progress.
result_bytesExecution-result byte count.
elapsed_nsDatabase-reported elapsed time in nanoseconds.
memory_usageDatabase-reported query memory in bytes, not total server or API-backend memory.

The response also retains inserted for compatibility: it is the numeric value of written_rows, or null when that count is unavailable. New clients should use written_rows. Summary fields are forwarded when the database provides a valid summary.

Without a transform, the API forwards the body unchanged using JSONAsObject. The database handles JSON validation, empty inputs, and insert errors. An error does not add an API-level rollback guarantee: any rows already written follow the database's insert behavior. A missing table can be auto-created even when the payload is empty or the database subsequently rejects it.

Optional transform for JSON body inserts:

POST /v1/tables/traces?transform=otlp-traces

Transforms flatten known source formats before insert.

See Transforms for supported input shapes and emitted rows.

Supported transforms:

  • otlp-traces
  • otlp-logs
  • otlp-metrics
  • cloudwatch-logs
  • cloudtrail
  • firehose

For AWS Firehose HTTP endpoint delivery, use:

POST /v1/tables/events?transform=firehose
X-Amz-Firehose-Access-Key: <rawtree-api-key>

Firehose records must contain base64-encoded data in records[].data. If the decoded value is a JSON object, the service inserts it as one row. If it is an array of JSON objects, the service inserts one row per object. If it is UTF-8 TSV text and columns is present, the service inserts one row per TSV line using those column names. If it is UTF-8 TSV text without columns, the service inserts one row with the decoded text in data. Other decoded formats return 400. Successful Firehose inserts return {requestId,timestamp}.

URL ingest uses query parameters:

POST /v1/tables/events?url=https%3A%2F%2Fexample.com%2Fevents.jsonl

The request stays open until the native RawTree URL import finishes. Success returns 200 with JSON such as {"inserted":1000}; inserted is null if RawTree does not provide a row count. Errors return a normal HTTP error response. There is no progress event stream.

Optionally pass query_id with a URL import to correlate it with RawTree query logs. If omitted, RawTree generates the ID. In both cases, the ID is returned in the X-ClickHouse-Query-Id response header, matching the query API. It is not added to the JSON body.

Transforms are not supported with URL inserts. If you use ?url=, transform the data before hosting it.

Use an API key, a permitted workload token, or a user bearer token. Database-role keys support only the operations listed in Authentication.

Parameters:

FieldLocationTypeRequiredNotes
urlquerystringNoOptional source URL. Mutually exclusive with request body.
query_idquerystringNoOptional query ID for correlating a URL import with ClickHouse query logs.
columnsquerystringNoOptional comma-separated column names for TSV data when using transform=firehose.
deduplicate_insertquerystringNoOptional ClickHouse insert deduplication setting: enable or disable.
insert_deduplication_tokenquerystringNoOptional custom ClickHouse insert deduplication token.

Request:

# Insert data into a table (auto-creates table if needed). URL imports wait for completion and return JSON.
curl -X POST "https://api.rawtree.com/v1/tables/events?database=analytics" \
  -H "Authorization: Bearer $RAWTREE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "action": "page_view",
  "region": "eu",
  "user": {
    "id": 42
  }
}'

Expected response: HTTP 200.

{
  "read_rows": "0",
  "read_bytes": "0",
  "written_rows": "1",
  "written_bytes": "57",
  "total_rows_to_read": "0",
  "result_rows": "0",
  "result_bytes": "0",
  "elapsed_ns": "1000000"
}

Errors: 400, 401, 413, 429. See API errors.

DELETE /v1/tables/{table}

Delete a table. Requires admin permission.

Use an API key, a permitted workload token, or a user bearer token. Database-role keys support only the operations listed in Authentication.

Request:

# Delete a table.
curl -X DELETE "https://api.rawtree.com/v1/tables/events?database=analytics" \
  -H "Authorization: Bearer $RAWTREE_API_KEY"

Expected response: HTTP 200.

{
  "deleted": true
}

Errors: 400, 401, 403. See API errors.