// for developers
Ripceipt API.
Drop-in for your stack.
One REST endpoint, AI vision under the hood, and predictable JSON on the way out. Typed SDKs for JS, Python, and Go. Signed webhooks. URI versioning so the schema stays put.
- SDKs
- JS · Python · Go
- Versioning
- /v1 stable
- Pricing
- From $5/mo
curl -X POST https://api.ripceipt.com/v1/receipts/upload \
-H "Authorization: Bearer key_live_…" \
-F "file=@receipt.jpg"The kit
Everything you'd expect.
Nothing you wouldn't.
AI extraction in one POST.
Send a file, a URL, or a base64 blob. Vision models read the receipt, return structured fields, and tag every value with a self-reported confidence score so your downstream code knows what to trust.
await receipts.create({
workspaceId: "ws_abc",
file,
retention: "delete_file",
});
Typed SDKs
Generated from the OpenAPI spec. Idiomatic per language. Auto-completion in every modern editor.
Signed webhooks
HMAC-SHA256 with timestamp. Stripe-style verification. Replay protection built in. Retried with exponential backoff.
X-Receipts-Signature: v1=…URI versioning
Versioned at /v1 from day one. We add fields and never break them. Breaking changes get /v2 and twelve months of notice.
Predictable JSON
Stable field order. ISO 8601 timestamps. Three-letter ISO 4217 currency. Confidence on every value.
Idiomatic errors
Typed error classes per language. Helpful messages. RFC 7807-style problem details on every 4xx and 5xx.
Quick start
Four steps from signup
to first receipt.
- 01
Sign up and grab a key
Create a workspace, then mint an API key from the dashboard. Keys are scoped to a workspace and can be rotated anytime.
bashstep 01# Stored as env var export RIPCEIPT_KEY="key_live_…" - 02
Install the SDK
Pick your language. Each SDK is generated from the same OpenAPI spec, so the shape of every method matches the REST endpoint exactly.
bashstep 02npm install @ripceipt/sdk # or pip install ripceipt # or go get github.com/ripceipt-dev/ripceipt-go - 03
POST your first receipt
A file, a URL, or a base64 string. The response is the structured receipt: line items, tax, payment, merchant, language, summary, and confidence.
tsstep 03const receipt = await client.receipts.create({ workspaceId: "ws_abc", file: fs.createReadStream("./receipt.jpg"), }); console.log(receipt.total); // 27.13 console.log(receipt.items); // [{ name, variant, … }] - 04
Listen for the webhook
For async flows, register a webhook URL and verify the HMAC signature on each delivery. Retries with exponential backoff. Replay-safe via timestamps.
tsstep 04// /webhooks/receipts import { verifyReceiptSignature } from "@ripceipt/sdk"; export async function POST(req) { if (!verifyReceiptSignature(req)) { return new Response("bad sig", { status: 401 }); } const { receipt } = await req.json(); await db.receipts.insert(receipt); return new Response("ok"); }
The schema
The receipt object,
in full.
One object, the same shape on every endpoint and every webhook. Add fields are backward-compatible additions only. Breaking changes get a new version.
idstring · prefixed (rcpt_…)
statusenum · processing | completed | failed
languagestring · ISO 639-1 (e.g. en-US)
currencystring · ISO 4217 (e.g. USD)
merchantobject · name, address, phone
paymentobject · method, brand, last4
itemsarray · name, variant, qty, price, tax_rate, confidence
subtotal · tax · totalnumber · decimals from currency
summarystring · plain-English paragraph
confidenceinteger · 1 to 99 (overall)
{
"id": "rcpt_2yK3pQ",
"status": "completed",
"language": "en-US",
"currency": "USD",
"merchant": {
"name": "Brew & Butter",
"address": "128 Palm St"
},
"payment": {
"method": "card",
"brand": "visa",
"last4": "4242"
},
"items": [
{
"id": "item_01",
"name": "Oat milk latte",
"variant": "Large",
"category": "Drinks",
"quantity": 1,
"price": 5.50,
"tax_rate": 0.085,
"confidence": 96
}
],
"subtotal": 25.00,
"tax": 2.13,
"total": 27.13,
"summary": "Five drinks and pastries from a coffee shop, paid by card.",
"confidence": 94
}Webhooks
Async by default,
signed by HMAC.
Fire-and-forget the upload, listen for the result. Stripe-style signatures, timestamps for replay protection, automatic retries with exponential backoff, and a delivery log for debugging.
- Step 01POST /receiptsYour code or dashboard
- Step 02AI extractionVision model reads it
- Step 03Webhook firesHMAC-signed POST
- Step 04Your handlerVerify & store
// Verify the HMAC signature on every delivery
import { createHmac, timingSafeEqual } from "node:crypto";
export function verifyReceiptSignature(req: Request, secret: string) {
const sig = req.headers.get("x-receipts-signature") ?? "";
const ts = req.headers.get("x-receipts-timestamp") ?? "";
// Reject anything older than 5 minutes (replay protection)
if (Math.abs(Date.now() / 1000 - Number(ts)) > 300) return false;
const body = await req.text();
const expected = createHmac("sha256", secret)
.update(`${ts}.${body}`)
.digest("hex");
return timingSafeEqual(
Buffer.from(sig.replace("v1=", "")),
Buffer.from(expected),
);
}Launch pricing
Plans that scale
with how much you extract.
Per-receipt cost drops as you scale, and a hard cap means you'll never wake up to a surprise bill.
- REST API and signed webhooks
- CSV, JSON, and XML export
- All retention modes
- Hard caps, no surprise bills
FAQ
The questions
we hear from devs.
Sync or async?
How do you handle retries?
Are there rate limits?
How big can files be?
How do I test in development?
What model is under the hood?
Do you have OpenAPI / SDKs?
How is the schema versioned?
Does it work as a tool for AI agents?
// ready when you are
Mint a key.
Make the call.
Five dollars a month gets you fifty receipts, the full API, signed webhooks, all three retention modes, and a hard cap so you never wake up to a surprise bill.