API quickstart
Authenticate with an API key (fin_sk_…) on metered /v1 routes, or use a Firebase ID token on /v1/account/*. No secrets belong in this static site.
1. Get an API key
Create an account, upgrade to Starter or higher, then create a key under Dashboard → API keys. The secret is shown once.
Authorization: Bearer fin_sk_live_…
Dashboard session calls use Firebase instead:
Authorization: Bearer <Firebase ID token>
2. Base URL
https://finura-api-245877296154.asia-south1.run.app
Health
Readiness probe (not /healthz):
curl -sS "$API_BASE/readyz"
# {"status":"ready","database":"ok",…}
Public demo surface status: GET /demo/health.
3. curl — refund decision
Debits 1 credit. Free / playground-only plans cannot call this with an API key (403).
curl -sS -X POST "$API_BASE/v1/financial-decisions/refunds" \
-H "Authorization: Bearer $FINURA_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"transaction_id": "txn_123",
"amount": 250000,
"currency": "INR",
"evidence_refs": ["dispute_form:df_1"],
"model_output": { "refund_reason": "unauthorised_upi" }
}'
4. JavaScript fetch
const res = await fetch(`${API_BASE}/v1/financial-decisions/refunds`, {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.FINURA_API_KEY}`,
"Content-Type": "application/json",
"Idempotency-Key": crypto.randomUUID(),
},
body: JSON.stringify({
transaction_id: "txn_123",
amount: 250000,
currency: "INR",
evidence_refs: ["dispute_form:df_1"],
model_output: { refund_reason: "unauthorised_upi" },
}),
});
if (res.status === 402) throw new Error("credits_exhausted");
if (res.status === 429) throw new Error("quota_exceeded");
const data = await res.json();
5. Goal runs
POST /v1/goals debits 5 credits per run when authenticated with a self-serve API key.
Credits
- 1 credit = 1 decision evaluation
- 1 goal run = 5 credits
- Free: 50 credits/month, playground only, hard-capped
- Starter: 1,000/mo · Business: 7,500/mo · overage configurable
Check balance: GET /v1/account/credits (Firebase Bearer) or watch 402 credits_exhausted on metered routes.
Errors
{ "detail": { "code": "credits_exhausted", "message": "…" } }
| Code | HTTP | Meaning |
|---|---|---|
credits_exhausted | 402 | Hard cap / no remaining credits |
quota_exceeded | 429 | Rate or quota limit |
plan_not_allowed | 403 | Feature not on current plan |
billing_disabled | 503 | Billing flag off |
Playground (no API key)
Signed-in users can run cases in the browser playground via POST /v1/account/playground/decisions without creating an API key.