Using the API¶
All Tilde API endpoints are served under /api/v1. This guide covers authentication, making requests, pagination, and error handling.
Python SDK
For Python, we recommend using the Python SDK which handles authentication, pagination, and error handling automatically. The examples below show raw HTTP requests for reference.
Base URL¶
Authentication¶
Tilde supports two authentication methods for programmatic access. If one method is not present or its credentials are expired, the server falls through to the next without returning an error.
1. API Key¶
Create an API key in the Tilde web UI or via the REST API. The token is shown only once at creation time. All code examples in this documentation use API key authentication.
Create an API key in the Tilde web UI or via the REST API, then configure the SDK:
import tilde
# Set the API key (token shown once at creation)
tilde.configure(api_key="YOUR_API_TOKEN")
# All SDK calls are now authenticated
repo = tilde.repository("my-team/my-data")
You can also set the TILDE_API_KEY environment variable to avoid hardcoding credentials:
2. Basic Auth¶
You can also use your email (or username) and password directly via HTTP Basic auth. This is supported for convenience but API keys are recommended for all programmatic access.
Pagination¶
List endpoints use keyset pagination. The response includes a pagination object:
{
"results": [...],
"pagination": {
"has_more": true,
"next_offset": "last-item-key",
"max_per_page": 100
}
}
To fetch the next page, pass after=<next_offset> as a query parameter. You can also set amount to control the page size (default: 100, max: 1000).
# First page (from latest committed state)
curl -H "Authorization: Bearer YOUR_API_TOKEN" \
"https://tilde.run/api/v1/organizations/my-team/repositories/my-data/objects?amount=100"
# Next page (use next_offset from previous response)
curl -H "Authorization: Bearer YOUR_API_TOKEN" \
"https://tilde.run/api/v1/organizations/my-team/repositories/my-data/objects?amount=100&after=data/file100.txt"
Error Handling¶
All errors return a JSON body with a human-readable message, a machine-readable code, and the request ID for debugging:
{
"message": "repository not found",
"code": "NOT_FOUND",
"request_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}
| HTTP Status | Code | Meaning |
|---|---|---|
| 400 | BAD_REQUEST |
Invalid input (missing fields, bad format) |
| 401 | UNAUTHORIZED |
Missing or invalid credentials |
| 403 | FORBIDDEN |
Authenticated but not permitted |
| 404 | NOT_FOUND |
Resource does not exist |
| 409 | CONFLICT |
Resource already exists (duplicate name, etc.) |
| 410 | GONE |
Resource has been permanently removed |
| 429 | RATE_LIMITED |
Too many requests |
| 500 | INTERNAL |
Server error |
Request ID
Include the request_id from error responses when reporting issues. It correlates with server-side logs for debugging.
Common Patterns¶
Working with Sessions¶
Sessions are temporary workspaces for staging changes before committing them. The typical workflow is: create a session, upload or delete objects within it, then commit the session (or roll it back if you want to discard changes).
# Create a session
curl -H "Authorization: Bearer YOUR_API_TOKEN" \
-X POST https://tilde.run/api/v1/organizations/my-team/repositories/my-data/sessions
# Upload a file in the session (3-step flow)
# Step 1: Get upload URL
PUT_RESP=$(curl -s -H "Authorization: Bearer YOUR_API_TOKEN" \
-X PUT "https://tilde.run/api/v1/organizations/my-team/repositories/my-data/object?session_id=SESSION_ID&path=datasets/new.csv")
UPLOAD_URL=$(echo "$PUT_RESP" | jq -r .upload_url)
UPLOAD_TOKEN=$(echo "$PUT_RESP" | jq -r .upload_token)
# Step 2: Upload directly
ETAG=$(curl -s -X PUT -T new.csv -H "Content-Type: text/csv" "$UPLOAD_URL" \
-D - -o /dev/null | grep -i '^etag:' | tr -d '\r' | cut -d' ' -f2 | tr -d '"')
# Step 3: Finalize to register in the catalog
curl -H "Authorization: Bearer YOUR_API_TOKEN" \
-X POST "https://tilde.run/api/v1/organizations/my-team/repositories/my-data/object/finalize?session_id=SESSION_ID&path=datasets/new.csv" \
-H "Content-Type: application/json" \
-d "{\"upload_token\": \"$UPLOAD_TOKEN\", \"checksum\": \"$ETAG\", \"content_type\": \"text/csv\"}"
# Commit the session
curl -H "Authorization: Bearer YOUR_API_TOKEN" \
-X POST "https://tilde.run/api/v1/organizations/my-team/repositories/my-data/sessions/SESSION_ID" \
-H "Content-Type: application/json" \
-d '{"message": "Add new dataset"}'
Uploading Large Files¶
The Tilde server is never in the data path for uploads. For very large files, use the multipart upload API to upload in parts.
import tilde
repo = tilde.repository("my-team/my-data")
with repo.session() as session:
# The SDK automatically uses the best upload strategy:
# - Files under 64 MB: single upload (Put Object → upload → Finalize)
# - Files 64 MB and above: multipart upload (initiate → upload parts → complete)
result = session.objects.put("data/large-file.parquet", open("large-file.parquet", "rb"))
print(result.path, result.etag)
session.commit("Add large dataset")
Rolling Back a Session¶
If you want to discard all staged changes, roll back the session instead of committing it.
Approving a Session¶
When an agent or automated process creates a session and stages changes, a human reviewer can inspect the changes and approve them. Approval commits the session and records the approver's identity in the commit metadata.
The Python SDK handles approval blocking automatically when committing. To review and approve a session created by another principal, use the REST API:
import requests
base = "https://tilde.run/api/v1/organizations/my-team/repositories/my-data"
headers = {"Authorization": "Bearer YOUR_API_TOKEN"}
# Review the changes
changes = requests.get(f"{base}/sessions/SESSION_ID/approve", headers=headers).json()
for entry in changes["results"]:
print(f" {entry['diff_type']}: {entry['path']}")
# Approve and commit
resp = requests.post(
f"{base}/sessions/SESSION_ID/approve",
headers=headers,
json={"message": "Approved: Add new dataset"},
)
print(f"Committed: {resp.json()['commit_id']}")
# Review the changes first
curl -H "Authorization: Bearer YOUR_API_TOKEN" \
"https://tilde.run/api/v1/organizations/my-team/repositories/my-data/sessions/SESSION_ID/approve"
# Approve and commit
curl -H "Authorization: Bearer YOUR_API_TOKEN" \
-X POST "https://tilde.run/api/v1/organizations/my-team/repositories/my-data/sessions/SESSION_ID/approve" \
-H "Content-Type: application/json" \
-d '{"message": "Approved: Add new dataset"}'
RBAC
Approving a session requires the ApproveSessionChanges permission. You can use this to separate who can create changes (agents with CreateSession + PutObject) from who can approve them (humans with ApproveSessionChanges). See the RBAC Reference for policy examples.
Reverting a Commit¶
If a commit introduced unwanted changes, you can revert it. Reverting creates a new commit in the repository that applies the inverse of the target commit's changes — files that were added are removed, files that were removed are restored, and modified files return to their pre-commit state. The original commit is preserved in history.
The revert succeeds only if every path affected by the target commit is unchanged in the repository's latest commit. If a subsequent commit modified one of those paths, the endpoint returns 409 Conflict.
# Revert a commit (auto-generates the message)
curl -H "Authorization: Bearer YOUR_API_TOKEN" \
-X POST "https://tilde.run/api/v1/organizations/my-team/repositories/my-data/commits/COMMIT_ID/revert" \
-H "Content-Type: application/json" \
-d '{}'
# Revert with a custom message
curl -H "Authorization: Bearer YOUR_API_TOKEN" \
-X POST "https://tilde.run/api/v1/organizations/my-team/repositories/my-data/commits/COMMIT_ID/revert" \
-H "Content-Type: application/json" \
-d '{"message": "Undo accidental upload"}'
Check the diff first
Before reverting, you can inspect what the commit changed using the Diff endpoint with the commit and its parent as left and right parameters.