REST API v1

API Integration Guide

Everything you need to integrate with the Suma REST API.

Getting Started

To use the Suma API you need an account and an API key.

  1. Log in to your Suma account at sumabot.online.
  2. Go to Settings > API Keys and create a new key. Copy it immediately — it’s shown only once.
  3. Include the key in every request as a Bearer token in the Authorization header.

Base URL: https://sumabot.online/api/v1

Authentication

All API requests require a Bearer token. API keys start with sb_ and are tied to your account. Include the token in the Authorization header.

Authorization: Bearer sb_your_api_key_here

Keys are hashed in our database — we cannot recover a lost key. Create a new one if needed.

Test Connection

Paste your API key below and click Test to verify it works. This calls GET /api/v1/ping.

Rate Limiting

The API allows 60 requests per minute by default. Rate limit info is included in response headers.

Header Description
X-RateLimit-Limit Maximum requests per window
X-RateLimit-Remaining Requests remaining in current window
X-RateLimit-Reset Unix timestamp when the window resets

Error Handling

Errors return a consistent JSON structure with a machine-readable code and a human-readable message.

{"error": {"code": "not_found", "message": "Resource not found"}}
Status Meaning
400 Bad Request
401 Unauthorized (invalid/missing API key)
403 Forbidden / Feature disabled
404 Not Found
422 Validation Error
429 Rate Limited

Pagination

List endpoints support offset-based pagination with page and per_page query parameters. Default: 25 items per page, max 100.

GET /api/v1/transactions?page=2&per_page=25

Paginated responses include a meta object with total counts.

{"data": [...], "meta": {"page": 2, "per_page": 25, "total": 150, "total_pages": 6}}

Code Examples

These examples show basic usage with transactions. The API supports 90+ operations across categories, budgets, alerts, recurring entries, groups, import/export, and more. See the full API reference below for all endpoints.

bash
# List transactions (with filters)
curl -s "https://sumabot.online/api/v1/transactions?type=expense&per_page=10" \
  -H "Authorization: Bearer sb_YOUR_KEY" | jq

# Create a transaction
curl -s -X POST https://sumabot.online/api/v1/transactions \
  -H "Authorization: Bearer sb_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": "50.00",
    "type": "expense",
    "description": "Lunch",
    "date": "2026-03-16",
    "currency": "USD",
    "category_id": "CATEGORY_UUID"
  }' | jq

# Delete a transaction
curl -s -X DELETE https://sumabot.online/api/v1/transactions/TRANSACTION_ID \
  -H "Authorization: Bearer sb_YOUR_KEY" | jq
bash
# List transactions (with filters)
http GET "https://sumabot.online/api/v1/transactions?type=expense&per_page=10" \
  Authorization:"Bearer sb_YOUR_KEY"

# Create a transaction
http POST https://sumabot.online/api/v1/transactions \
  Authorization:"Bearer sb_YOUR_KEY" \
  amount="50.00" type="expense" description="Lunch" \
  date="2026-03-16" currency="USD" category_id="CATEGORY_UUID"

# Delete a transaction
http DELETE https://sumabot.online/api/v1/transactions/TRANSACTION_ID \
  Authorization:"Bearer sb_YOUR_KEY"
python
import requests

BASE = "https://sumabot.online/api/v1"
HEADERS = {"Authorization": "Bearer sb_YOUR_KEY"}

# List transactions (with filters)
resp = requests.get(f"{BASE}/transactions", headers=HEADERS, params={
    "type": "expense",
    "per_page": 10,
})
for tx in resp.json()["data"]:
    print(f"{tx['date']} {tx['description']}: {tx['amount']} {tx['currency']}")

# Create a transaction
resp = requests.post(f"{BASE}/transactions", headers=HEADERS, json={
    "amount": "50.00",
    "type": "expense",
    "description": "Lunch",
    "date": "2026-03-16",
    "currency": "USD",
    "category_id": "CATEGORY_UUID",
})
tx = resp.json()["data"]
print(f"Created: {tx['id']}")

# Delete a transaction
requests.delete(f"{BASE}/transactions/{tx['id']}", headers=HEADERS)
javascript
const BASE = "https://sumabot.online/api/v1";
const HEADERS = {
  "Authorization": "Bearer sb_YOUR_KEY",
  "Content-Type": "application/json",
};

// List transactions (with filters)
const resp = await fetch(`${BASE}/transactions?type=expense&per_page=10`, {
  headers: HEADERS,
});
const { data, meta } = await resp.json();
console.log(`Page ${meta.page} of ${meta.total_pages}`);

// Create a transaction
const created = await fetch(`${BASE}/transactions`, {
  method: "POST",
  headers: HEADERS,
  body: JSON.stringify({
    amount: "50.00",
    type: "expense",
    description: "Lunch",
    date: "2026-03-16",
    currency: "USD",
    category_id: "CATEGORY_UUID",
  }),
});
const { data: tx } = await created.json();
console.log(`Created: ${tx.id}`);

// Delete a transaction
await fetch(`${BASE}/transactions/${tx.id}`, {
  method: "DELETE",
  headers: HEADERS,
});

Response

json
{
  "data": {
    "id": "a1b2c3d4-...",
    "amount": "50.00",
    "type": "expense",
    "description": "Lunch",
    "date": "2026-03-16",
    "currency": "USD",
    "category_id": "e5f6a7b8-...",
    "category": { "id": "e5f6a7b8-...", "name": "Food", "type": "expense" },
    "group_id": null,
    "metadata": { "source": "api" },
    "inserted_at": "2026-03-16T12:00:00Z",
    "updated_at": "2026-03-16T12:00:00Z"
  }
}

Full API Reference

This page covers the basics. The full API has 90+ operations across 44 resource groups. Explore the interactive documentation for all endpoints, parameters, and response schemas.

The Swagger UI lets you try endpoints directly in the browser with your API key.