Docs
Guides
API walkthrough

API walkthrough

This guide walks through how to accomplish common Braintrust use cases with the API. Each example is implemented in a particular language, for legibility, but the API itself is language-agnostic. To learn more about the API, see the full API spec.

Running an experiment

import os
from uuid import uuid4
 
import requests
 
API_URL = "https://api.braintrustdata.com/v1"
headers = {"Authorization": "Bearer " + os.environ["BRAINTRUST_API_KEY"]}
 
if __name__ == "__main__":
    # Create a project, if it does not already exist
    project = requests.post(f"{API_URL}/project", headers=headers, json={"name": "rest_test"}).json()
    print(project)
 
    # Create an experiment. This should always be new
    experiment = requests.post(
        f"{API_URL}/experiment", headers=headers, json={"name": "rest_test", "project_id": project["id"]}
    ).json()
    print(experiment)
 
    # Log some stuff
    for i in range(10):
        resp = requests.post(
            f"{API_URL}/experiment/{experiment['id']}/insert",
            headers=headers,
            json={"events": [{"id": uuid4().hex, "input": 1, "output": 2, "scores": {"accuracy": 0.5}}]},
        )
        if not resp.ok:
            raise Exception(f"Error: {resp.status_code} {resp.text}: {resp.content}")

Downloading a dataset, using pagination

// If you're self-hosting Braintrust, then use your stack's API URL, e.g.
//  https://0o71finhla.execute-api.us-east-1.amazonaws.com/api
export const BRAINTRUST_API_URL = "https://api.braintrustdata.com";
export const API_KEY = process.env.BRAINTRUST_API_KEY;
 
export async function* paginateDataset(args: {
  project: string;
  dataset: string;
  version?: string;
  // Number of rows to fetch per request. You can adjust this to be a lower number
  // if your rows are very large (e.g. several MB each).
  perRequestLimit?: number;
}) {
  const { project, dataset, version, perRequestLimit } = args;
  const headers = {
    Accept: "application/json",
    "Accept-Encoding": "gzip",
    Authorization: `Bearer ${API_KEY}`,
  };
  const fullURL = `${BRAINTRUST_API_URL}/v1/dataset?project_name=${encodeURIComponent(
    project,
  )}&dataset_name=${encodeURIComponent(dataset)}`;
  const ds = await fetch(fullURL, {
    method: "GET",
    headers,
  });
  if (!ds.ok) {
    throw new Error(
      `Error fetching dataset metadata: ${ds.status}: ${await ds.text()}`,
    );
  }
  const dsJSON = await ds.json();
  const dsMetadata = dsJSON.objects[0];
  if (!dsMetadata?.id) {
    throw new Error(`Dataset not found: ${project}/${dataset}`);
  }
 
  let cursor: string | null = null;
  while (true) {
    const body: string = JSON.stringify({
      query: {
        from: {
          op: "function",
          name: { op: "ident", name: ["dataset"] },
          args: [{ op: "literal", value: dsMetadata.id }],
        },
        select: [{ op: "star" }],
        limit: perRequestLimit,
        cursor,
      },
      fmt: "jsonl",
      version,
    });
    const response = await fetch(`${BRAINTRUST_API_URL}/btql`, {
      method: "POST",
      headers,
      body,
    });
    if (!response.ok) {
      throw new Error(
        `Error fetching rows for ${dataset}: ${
          response.status
        }: ${await response.text()}`,
      );
    }
 
    cursor =
      response.headers.get("x-bt-cursor") ??
      response.headers.get("x-amz-meta-bt-cursor");
 
    // Parse jsonl line-by-line
    const allRows = await response.text();
    const rows = allRows.split("\n");
    let rowCount = 0;
    for (const row of rows) {
      if (!row.trim()) {
        continue;
      }
      yield JSON.parse(row);
      rowCount++;
    }
 
    if (rowCount === 0) {
      break;
    }
  }
}
 
async function main() {
  for await (const row of paginateDataset({
    project: "Your project name", // Replace with your project name
    dataset: "Your dataset name", // Replace with your dataset name
    perRequestLimit: 100,
  })) {
    console.log(row);
  }
}
 
main();