Agentic API — Example Calls
Three minimal flows for the Cash Runway agentic surface: curl, TypeScript, and Python. Each example assumes the API key is provisioned under Settings → API keys and carries the READ_BANK + READ_FORECAST scopes.
The same bearer header works for every endpoint:
http
Authorization: Bearer cr_live_<prefixId>_<secret>Full spec: /api/agent/openapi.json.
curl
1. Session bootstrap (/status)
bash
curl -sS https://app.cashrunway.ai/api/agent/status \
-H "Authorization: Bearer $CASHRUNWAY_API_KEY" | jq2. Latest cash position
bash
curl -sS https://app.cashrunway.ai/api/agent/cash-position \
-H "Authorization: Bearer $CASHRUNWAY_API_KEY" \
-D - | jqNote the -D - flag — the X-Cash Runway-* headers carry subscription + quota state and are worth reading on every call.
3. 13-week forecast
bash
curl -sS "https://app.cashrunway.ai/api/agent/forecast?scenarioId=scn_abc" \
-H "Authorization: Bearer $CASHRUNWAY_API_KEY" | jq '.weeks[] | {weekStart, closing, net}'TypeScript (fetch)
ts
const BASE = 'https://app.cashrunway.ai/api/agent';
const KEY = process.env.CASHRUNWAY_API_KEY!;
async function agentGet<T>(path: string): Promise<T> {
const res = await fetch(`${BASE}${path}`, {
headers: { Authorization: `Bearer ${KEY}` },
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
return res.json() as Promise<T>;
}
// 1. Session bootstrap
const status = await agentGet<{
subscription: { status: string; plan: string; trialDaysRemaining?: number };
quota: { used: number; remaining: number };
}>('/status');
console.log(`${status.subscription.plan} — ${status.quota.remaining} queries remaining`);
// 2. Cash position with agent notes
const cash = await agentGet<{
startingCash: string;
accounts: Array<{ id: string; name: string; balance: string }>;
notesForAgent: Array<{ kind: string; severity: string; text: string }>;
billingAlert?: { severity: 'warn' | 'critical'; message: string };
}>('/cash-position');
if (cash.billingAlert) console.warn('Billing alert:', cash.billingAlert.message);
console.log('Opening cash:', cash.startingCash);
// 3. Forecast
const forecast = await agentGet<{
weeks: Array<{ weekStart: string; closing: string; net: string }>;
}>('/forecast');
for (const w of forecast.weeks) {
console.log(`${w.weekStart}: closing=${w.closing} net=${w.net}`);
}Python
python
import os, requests
BASE = "https://app.cashrunway.ai/api/agent"
KEY = os.environ["CASHRUNWAY_API_KEY"]
def agent_get(path: str) -> dict:
r = requests.get(f"{BASE}{path}", headers={"Authorization": f"Bearer {KEY}"})
r.raise_for_status()
return r.json()
# 1. Session bootstrap
status = agent_get("/status")
print(f"{status['subscription']['plan']} — {status['quota']['remaining']} remaining")
# 2. Cash position
cash = agent_get("/cash-position")
if alert := cash.get("billingAlert"):
print(f"[{alert['severity']}] {alert['message']}")
print("Opening cash:", cash["startingCash"])
# 3. Forecast
fc = agent_get("/forecast")
for w in fc["weeks"]:
print(f"{w['weekStart']}: closing={w['closing']} net={w['net']}")Headers to watch
Every successful response carries billing + query-credit context in headers, so you don't have to parse the body to decide whether to pace yourself:
| Header | Value |
|---|---|
X-CashRunway-Subscription | trialing / active / past_due / canceled / trial_ended |
X-CashRunway-Plan | Subscription display name (legacy — read the usage block for the query-credit plan) |
X-CashRunway-Trial-Days-Remaining | integer, only when trialing |
X-CashRunway-Reset-Minutes | integer — minutes until the next query credit frees up |
X-CashRunway-Quota-Remaining | integer — legacy daily bucket (prefer the usage block) |
X-CashRunway-Quota-Reset | ISO timestamp — legacy daily bucket (prefer usage.windowResetAt) |
When something needs action, a billingAlert field also appears in the JSON body. Its absence on a healthy call is itself the positive signal.