Reference

API Reference

SDK version 0.9. All endpoints require an API key passed as X-Relai-Key in the request header. Search for a method or endpoint below.

POST /v1/capture

relai.capture()

Captures the execution context of an agent run for later replay. Call this inside your exception handler or after any agent turn that produced an unexpected result. Returns a bundle_id you can pass to relai verify.

Request body

JSON POST /v1/capture
{
  "agent_id": "order-processing-v2",
  "run_id": "run_8f2a1c9e",
  "inputs": {
    "user_message": "Cancel my last order and issue a refund.",
    "conversation_history": [
      { "role": "user", "content": "I need help with order #8821" },
      { "role": "assistant", "content": "I found order #8821. What would you like to do?" }
    ]
  },
  "tool_state": {
    "orders_api_version": "2024-01",
    "user_id": "usr_49f3c",
    "cart_id": null
  },
  "model": "gpt-4o-2024-08-06",
  "temperature": 0.2,
  "failure_signal": "tool_call_error",
  "error_message": "orders.cancel: permission denied for user role=viewer",
  "metadata": {
    "environment": "production",
    "region": "us-east-1"
  }
}

Response

JSON 200 OK
{
  "bundle_id": "bndl_4a7f29cd83e1",
  "status": "captured",
  "replay_url": "https://app.getrelai.org/replay/bndl_4a7f29cd83e1",
  "expires_at": "2026-07-25T00:00:00Z",
  "sha256": "e3b0c44298fc1c149afbf4c8996fb924"
}

GET /v1/bundles/{bundle_id}

listReplays()

Retrieves a single capture bundle by its ID. The response includes the full execution context: inputs, tool state, model version, and the original failure signal. Use this to inspect what was recorded before running replay.

Path parameters

JSON GET /v1/bundles/bndl_4a7f29cd83e1
{
  "bundle_id": "bndl_4a7f29cd83e1",
  "agent_id": "order-processing-v2",
  "captured_at": "2026-06-13T14:22:10Z",
  "failure_signal": "tool_call_error",
  "model": "gpt-4o-2024-08-06",
  "inputs": { "...": "see /v1/capture schema" },
  "tool_state": { "...": "snapshotted at capture time" },
  "replay_count": 3,
  "last_replayed_at": "2026-06-14T09:15:44Z"
}

POST /v1/fixes/propose

proposefix()

Attaches a proposed code diff to a bundle. When the fix is submitted, Relai automatically replays the original failure context against the patched agent and returns a structured pass/fail verdict. The diff must be in unified diff format.

Request body

JSON POST /v1/fixes/propose
{
  "bundle_id": "bndl_4a7f29cd83e1",
  "diff": "--- a/tools/orders.py\n+++ b/tools/orders.py\n@@ -44,7 +44,7 @@\n-    if user.role == 'viewer':\n+    if user.role in ('viewer', 'support'):\n         raise PermissionError('permission denied')",
  "commit_sha": "3f1e7a8",
  "pr_url": "https://github.com/yourorg/agent/pull/82",
  "notes": "Extend cancel permission to support role per product spec"
}

Response

JSON 200 OK
{
  "fix_id": "fix_7b3c90da",
  "bundle_id": "bndl_4a7f29cd83e1",
  "replay_status": "running",
  "estimated_completion_ms": 4200,
  "webhook_url": "https://app.getrelai.org/hooks/fix_7b3c90da"
}

GET /v1/fixes/{fix_id}/status

getStatus()

Polls the replay status of a submitted fix. Once status transitions to complete, the verdict field contains the full structured diff result indicating whether the fix resolved the original failure.

Response

JSON 200 OK
{
  "fix_id": "fix_7b3c90da",
  "bundle_id": "bndl_4a7f29cd83e1",
  "status": "complete",
  "verdict": "pass",
  "replay_duration_ms": 3840,
  "assertion_results": [
    {
      "assertion": "no_tool_call_error",
      "result": "pass",
      "detail": "orders.cancel completed with status 200"
    },
    {
      "assertion": "output_contains_confirmation",
      "result": "pass",
      "detail": "Response includes 'refund initiated'"
    }
  ],
  "completed_at": "2026-06-14T09:20:22Z"
}

CI integration

Run Relai replay checks as part of your existing CI pipeline. The relai verify CLI command exits 0 on pass and non-zero on failure, so it integrates with any CI system that reads exit codes.

GitHub Actions example

YAML .github/workflows/relai.yml
name: Relai Replay Gate

on:
  pull_request:
    branches: [main]

jobs:
  replay-gate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Install Relai CLI
        run: pip install relai-sdk
      - name: Run replay suite
        env:
          RELAI_API_KEY: ${{ secrets.RELAI_API_KEY }}
        run: relai verify --suite production-failures --fail-on-regression

CLI options

BASH Terminal
relai verify [options]

  --suite <name>         Named bundle suite to replay (default: all)
  --bundle <bundle_id>   Replay a single bundle
  --fix <fix_id>         Verify a specific fix proposal
  --timeout <ms>         Per-replay timeout in milliseconds (default: 30000)
  --fail-on-regression   Exit 1 if any previously-passing bundle now fails
  --json                 Output results as JSON to stdout

Response codes

Code Meaning Common cause
200 OK Request succeeded.
400 Bad request Missing required field or malformed JSON body.
401 Unauthorized API key absent or expired.
404 Not found The requested bundle_id or fix_id does not exist.
409 Conflict A replay is already running for this bundle.
429 Rate limited See rate limits below.
500 Internal error Retry with exponential backoff; contact support if persistent.

Error response shape

JSON Error envelope
{
  "error": {
    "code": "bundle_not_found",
    "message": "No bundle with ID bndl_00000000 found in this workspace.",
    "request_id": "req_9c1d4ef7"
  }
}

Rate limits

Rate limits apply per API key. Exceeding a limit returns HTTP 429 with a Retry-After header (seconds until the window resets).

Endpoint Rate (free) Rate (pro)
POST /v1/capture 60 / min 600 / min
GET /v1/bundles/* 120 / min 1200 / min
POST /v1/fixes/propose 10 / min 100 / min
GET /v1/fixes/*/status 120 / min 1200 / min