Documentation
Branch Pilot exposes one endpoint per decision. This page covers authentication, the request and response formats, errors, and the playground-to-production workflow.
Authentication
Create an API key in Settings → API keys. Test and live keys behave the same for now; use them to separate environments in your own tooling. Send the key as a Bearer token.
Authorization: Bearer bp_live_8ec3887f…Make a decision
POST the input your decision expects. Declared fields are validated; fields marked PII are pseudonymized before any model call.
curl -X POST https://api.branchpilot.ai/v1/decide/lead-routing \
-H "Authorization: Bearer bp_live_…" \
-H "Content-Type: application/json" \
-d '{
"input": {"email": "anna@acme.com", "message": "Could we get a quote for 40 seats?"},
"options": {"engine": "jev"}
}'input— string, object or array; validated against the declared fields.options.version— call a specific version instead of the live one.options.engine—"jev"or"llm"to force an engine for this call.
Response
status is ok, uncertain or pending. For route decisions, choice is the selected option or "__uncertain__". Score decisions add score (0–100), raw_score and legend; classify decisions add labels.
{
"run_id": "3f0b2c1e-…",
"decision": "lead-routing",
"version": 3,
"status": "ok",
"choice": "sales",
"probabilities": {"sales": 0.87, "support": 0.09, "spam": 0.04},
"confidence": 0.87,
"confidence_source": "calibrated",
"engine": "jev",
"model": "jev-1.13.0",
"latency_ms": 212,
"pii_redacted": 1
}{ "status": "uncertain", "choice": "__uncertain__", "confidence": 0.51, … }
{ "status": "pending", "review_url": "https://app.branchpilot.ai/review/…", … }Errors
| HTTP | code | |
|---|---|---|
400 | invalid_json, invalid_payload | Body is not JSON, or input does not match the declared fields (details lists the problems). |
401 | unauthorized | Missing, invalid or revoked API key. |
404 | not_found | Unknown decision slug or version. |
409 | no_live_version | The decision has no published version. |
413 | payload_too_large | Body larger than 128 KB. |
429 | quota_exceeded | Monthly quota reached; Retry-After tells you when it resets. |
502 | engines_unavailable | Neither engine could answer (details lists the attempts). |
{
"error": {
"code": "invalid_payload",
"message": "Input does not match the decision context",
"details": ["input.email: required"]
}
}From playground to production
Edit the draft, run your test cases, publish. The endpoint always serves the live version; pass options.version to call a specific one. Every call is logged with its pseudonymized input, probabilities, engine, latency and cost.
OpenAPI specification
The full API is described in an OpenAPI 3.1 document you can import into Postman, Insomnia or a code generator.