API Reference - Braintrust
Braintrust API Overview
The Braintrust API allows you to interact with all aspects of the Braintrust platform programmatically. You can use it to:
- Create and manage projects, experiments, and datasets
- Log traces and metrics
- Manage prompts, tools, and scorers
- Configure access control and permissions
- Retrieve and analyze results
The API is defined by an OpenAPI specification published at braintrust-openapi on GitHub.
Base URL
The base URL depends on your organization’s data plane region:
| Region | Base URL |
|---|---|
| US | https://api.braintrust.dev |
| EU | https://api-eu.braintrust.dev |
| Self-hosted | Your custom data plane URL |
You can find your API URL in Settings > Data plane.
Authentication
Authenticate requests with your API key in the Authorization header:
curl https://api.braintrust.dev/v1/project \
-H "Authorization: Bearer $BRAINTRUST_API_KEY"
Create API keys in Settings > API keys.
SDKs
While you can call the API directly, we recommend using one of our official SDKs:
[**TypeScript SDK**
Official TypeScript/JavaScript SDK](/content/docs/sdks/typescript/quickstart/index.html)
[**Python SDK**
Official Python SDK](/content/docs/sdks/python/quickstart/index.html)
[**Go SDK**
Official Go SDK](/content/docs/sdks/go/quickstart/index.html)
[**Ruby SDK**
Official Ruby SDK](/content/docs/sdks/ruby/quickstart/index.html)
[**Java SDK**
Official Java SDK](/content/docs/sdks/java/quickstart/index.html)
[**C# SDK**
Official C# SDK](/content/docs/sdks/csharp/quickstart/index.html)
[**Kotlin SDK**
Official Kotlin SDK](https://github.com/braintrustdata/braintrust-kotlin)
API resources
The API is organized around REST principles. Each resource has predictable URLs and uses HTTP response codes to indicate API errors.
Project resources
- Projects: Organize your AI features and experiments
- Experiments: Run and track evaluation experiments
- Datasets: Manage test data for evaluations
- Logs: Store and query production traces
- Prompts: Version control your prompts
- Functions: Manage tools, scorers, and workflows
- Evals: Configure and run evaluations
- Scores: Define custom scoring functions
- Tags: Organize and filter project resources
- Automations: Configure automated workflows
- Views: Create and manage custom data views
Organization resources
- Organizations: Manage your organization settings
- Users: Manage team members
- Groups: Organize users into teams
- Roles: Define permission levels
- ACLs: Configure fine-grained access control
- API keys: Manage authentication credentials
- Service tokens: Generate service-level authentication tokens
Configuration resources
- AI secrets: Securely store API keys and credentials
- Environment variables: Manage environment-specific configuration
- MCP servers: Configure Model Context Protocol servers
- Proxy: Configure proxy settings for API requests
Response format
All API responses are returned in JSON format. Successful responses will have a 2xx status code, while errors will return 4xx or 5xx status codes with error details.
Rate limits
The API uses rate limiting to ensure fair usage. Rate limits are applied per organization and endpoint. If you exceed the rate limit, you’ll receive a 429 Too Many Requests response.
Query data
Query your logs, experiments, and datasets with SQL through the /btql endpoint.
Query logs and experiments
Use the /btql endpoint to query data with SQL syntax. Data-source functions like project_logs() and experiment() accept an object name or its ID. See Querying by name for details. To control query lint warnings, set the lint_mode parameter — see Lint warnings.
TypeScript Example
const API_URL = "https://api.braintrust.dev/";
const headers = {
Authorization: `Bearer ${process.env.BRAINTRUST_API_KEY}`,
};
const query = `
SELECT id, input, output, scores
FROM project_logs('your-project-id', shape => 'traces')
WHERE scores.accuracy > 0.8
LIMIT 100
`;
const response = await fetch(`${API_URL}/btql`, {
method: "POST",
headers,
body: JSON.stringify({ query, fmt: "json" }),
});
const data = await response.json();
for (const row of data.data) {
console.log(row);
}
Python Example
import os
import requests
API_URL = "https://api.braintrust.dev/"
headers = {"Authorization": "Bearer " + os.environ["BRAINTRUST_API_KEY"]}
query = """
SELECT id, input, output, scores
FROM project_logs('your-project-id', shape => 'traces')
WHERE scores.accuracy > 0.8
LIMIT 100
"""
response = requests.post(
f"{API_URL}/btql",
headers=headers,
json={"query": query, "fmt": "json"},
).json()
for row in response["data"]:
print(row)
Filter experiments by metadata
Filter experiments by metadata field equality using the metadata query parameter on GET /v1/experiment. Pass a JSON-serialized object to match experiments where all specified fields are equal — including nested paths:
Python Example
import json
import os
import requests
API_URL = "https://api.braintrust.dev/v1"
headers = {"Authorization": "Bearer " + os.environ["BRAINTRUST_API_KEY"]}
response = requests.get(
f"{API_URL}/experiment",
headers=headers,
params=dict(
project_id="your-project-id",
metadata=json.dumps({"env": "production", "model": {"name": "gpt-5-mini"}}),
),
)
experiments = response.json().get("objects", [])
for experiment in experiments:
print(experiment["id"], experiment["name"])
Fetch experiment results
Query experiments to check review status or other metrics:
Python Example
import os
import requests
API_URL = "https://api.braintrust.dev/"
headers = {"Authorization": "Bearer " + os.environ["BRAINTRUST_API_KEY"]}
def fetch_experiment_review_status(experiment_id: str) -> dict:
query = f"""
SELECT
sum(CASE WHEN scores."response quality" IS NOT NULL THEN 1 ELSE 0 END) AS reviewed,
sum(CASE WHEN is_root THEN 1 ELSE 0 END) AS total
FROM experiment('{experiment_id}')
"""
return requests.post(
f"{API_URL}/btql",
headers=headers,
json={"query": query, "fmt": "json"},
).json()
EXPERIMENT_ID = "your-experiment-id"
print(fetch_experiment_review_status(EXPERIMENT_ID))
Export data
Export logs, experiments, or datasets to JSON or Parquet:
Shell Script Example
# Export to JSON
curl https://api.braintrust.dev/btql \
-H "Authorization: Bearer $BRAINTRUST_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"query": "SELECT * FROM project_logs(\"project-id\") traces",
"fmt": "json"
}' > export.json
# Export to Parquet
curl https://api.braintrust.dev/btql \
-H "Authorization: Bearer $BRAINTRUST_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"query": "SELECT * FROM project_logs(\"project-id\") traces",
"fmt": "parquet"
}' > export.parquet
Write and manage data
Run experiments
Create and run experiments programmatically:
Python Example
import os
from uuid import uuid4
import requests
API_URL = "https://api.braintrust.dev/v1"
headers = {"Authorization": "Bearer " + os.environ["BRAINTRUST_API_KEY"]}
# Create a project
project = requests.post(
f"{API_URL}/project",
headers=headers,
json={"name": "My Project"}
).json()
# Create an experiment
experiment = requests.post(
f"{API_URL}/experiment",
headers=headers,
json={"name": "Test Run", "project_id": project["id"]}
).json()
# Insert experiment results
for i in range(10):
requests.post(
f"{API_URL}/experiment/{experiment['id']}/insert",
headers=headers,
json={
"events": [{
"id": uuid4().hex,
"input": {"question": f"Test {i}"},
"output": f"Answer {i}",
"scores": {"accuracy": 0.9}
}]
}
)
Log programmatically
Insert logs via the API:
Python Example
import os
from uuid import uuid4
import requests
API_URL = "https://api.braintrust.dev/v1"
headers = {"Authorization": "Bearer " + os.environ["BRAINTRUST_API_KEY"]}
# Get or create project
project = requests.post(
f"{API_URL}/project",
headers=headers,
json={"name": "My Project"}
).json()
# Insert log event
requests.post(
f"{API_URL}/project_logs/{project['id']}/insert",
headers=headers,
json={
"events": [{
"id": uuid4().hex,
"input": {"question": "What is 2+2?"},
"output": "4",
"scores": {"accuracy": 1.0},
"metadata": {"environment": "production"}
}]
}
)
Delete logs
Mark logs for deletion by setting _object_delete:
Python Example
import os
import requests
API_URL = "https://api.braintrust.dev/"
headers = {"Authorization": "Bearer " + os.environ["BRAINTRUST_API_KEY"]}
# Find logs to delete
query = """
SELECT id
FROM project_logs('project-id', shape => 'traces')
WHERE metadata.user_id = 'test-user'
"""
response = requests.post(
f"{API_URL}/btql",
headers=headers,
json={"query": query}
).json()
ids = [row["id"] for row in response["data"]]
# Delete logs
delete_events = [{"id": id, "_object_delete": True} for id in ids]
requests.post(
f"{API_URL}/v1/project_logs/project-id/insert",
headers=headers,
json={"events": delete_events}
)
Impersonate users
User impersonation lets a privileged user perform an operation on behalf of another user, using the impersonated user’s identity and permissions. To impersonate a user, set the x-bt-impersonate-user header to the ID or email of the user you want to impersonate.
TypeScript Example
// If you're self-hosting Braintrust, then use your stack's Universal API URL, e.g.
// https://dfwhllz61x709.cloudfront.net
export const BRAINTRUST_API_URL = "https://api.braintrust.dev";
export const API_KEY = process.env.BRAINTRUST_API_KEY;
async function main() {
const response = await fetch(`${BRAINTRUST_API_URL}/v1/project`, {
method: "POST",
headers: {
"Authorization": `Bearer ${API_KEY}`,
"x-bt-impersonate-user": process.env.USER_EMAIL,
},
body: JSON.stringify({
name: "my-project",
org_name: process.env.ORG_NAME,
}),
});
console.log(await response.json());
}
main();
Next steps
- Explore the complete API reference for all available endpoints.
- Learn about SQL querying to analyze your data.
- Review system limits for API usage constraints.
- Check out the Python SDK or TypeScript SDK documentation.