SnapCost SnapCost API

SnapCost API

A clean REST API for receipts, invoices, and tax-ready reports. JSON in, JSON out. Bearer-token auth. Built for accountants, ERP integrations, and your own automations.

Base URL

https://snapcost.app/api

Format

JSON request & response bodies, UTF-8.

Auth

HTTP Bearer with an API key.

Plan

API access requires the Business plan.

Authentication

Every request must include an Authorization header carrying your API key.

Authorization: Bearer sk_live_••••••••••••••••••••••••••••••••

API keys are tied to a single SnapCost account and inherit that account's permissions and plan limits. They behave identically to a logged-in user session — there is no separate scoping system today.

Treat keys like passwords. Never commit them to source control or expose them in browser-side code. Rotate immediately if a key may have leaked.

Managing API keys

Generate, list, and revoke keys from the SnapCost dashboard, or use the management endpoints below (these endpoints require a logged-in JWT, not an API key, to prevent privilege escalation).

GET/api/keysList your keys
POST/api/keysCreate a new key
DELETE/api/keys/:idRevoke a key

Create a key

POST /api/keys
Content-Type: application/json

{ "name": "Zapier production" }

Response

{
  "id":        "9c1f…",
  "name":      "Zapier production",
  "prefix":    "sk_live_AbC",
  "plaintext": "sk_live_AbCDeFGhIJKlMnOPqRsTUVwxYZ0123456789…",
  "createdAt": "2026-04-21T10:42:18.000Z",
  "note":      "Store this key now — the full value will not be shown again."
}

The full plaintext key is only returned once, at creation. SnapCost stores a SHA-256 hash and cannot recover the original value. Limit: 10 active keys per account.

Quick start

curl https://snapcost.app/api/receipts \
  -H "Authorization: Bearer $SNAPCOST_API_KEY"
const res = await fetch('https://snapcost.app/api/receipts', {
  headers: { Authorization: `Bearer ${process.env.SNAPCOST_API_KEY}` },
});
const { receipts } = await res.json();
import os, requests

r = requests.get(
    "https://snapcost.app/api/receipts",
    headers={"Authorization": f"Bearer {os.environ['SNAPCOST_API_KEY']}"},
)
receipts = r.json()["receipts"]

Receipts

Receipts are scanned or manually entered expense records.

GET/api/receiptsList receipts
GET/api/receipts/:idFetch one receipt
POST/api/receiptsCreate a receipt
PUT/api/receipts/:idUpdate a receipt
DELETE/api/receipts/:idDelete a receipt

Create a receipt

FieldTypeNotes
merchantstringrequiredVendor name
amountnumberrequiredTotal in currency
currencystringoptionalISO 4217, defaults to your account currency
datestringrequiredISO date (YYYY-MM-DD)
categorystringoptionale.g. travel, meals
notesstringoptionalFree-text memo

Invoices

Invoices and quotes you issue to clients. Pro+ accounts can also access Factur-X / PDP / e-reporting endpoints.

GET/api/invoicesList invoices & quotes
POST/api/invoicesCreate an invoice or quote
GET/api/invoices/:idFetch one
PUT/api/invoices/:idUpdate
DELETE/api/invoices/:idDelete
GET/api/invoices/:id/facturx-pdfDownload Factur-X PDF (Pro+)
POST/api/invoices/:id/pdp/sendSubmit to PDP (Pro+)

Reports

Generate tax-ready summaries for any date range.

GET/api/reportsList saved reports
POST/api/reportsGenerate a report
GET/api/reports/:idFetch a report

Errors

SnapCost uses standard HTTP status codes. Failures always return JSON with an error field, sometimes a message, and occasionally an upgradeUrl when a paid plan is required.

StatusMeaning
400Malformed request — missing or invalid parameters
401Missing, invalid, or revoked API key / token
402Free-plan quota exhausted — upgrade required
403Endpoint requires a higher plan (e.g. Pro+)
404Resource not found or not owned by your account
429Too many requests — see rate limits below
5xxTransient server error — safe to retry with backoff

Rate limits

Default limit is 100 requests per minute per IP, applied across all /api/* endpoints. Auth endpoints are stricter. If you need more, contact support with your use case.

Versioning

The API today is unversioned and strictly additive — we add fields and endpoints without breaking existing clients. Any breaking change will ship under a new /api/v2/… prefix with a deprecation window of at least 6 months.