Code Examples
These examples show common API operations. All examples assume you have stored your API token in the OGARNIAI_API_TOKEN environment variable.
Basic authenticated request
Section titled “Basic authenticated request”curl -X GET "https://api.ogarni.ai/api/weekly-summaries/latest" \ -H "X-API-Key: $OGARNIAI_API_TOKEN" \ -H "Accept: application/json"List recent documents
Section titled “List recent documents”curl -X GET "https://api.ogarni.ai/api/PurchaseDocuments/my?sortBy=purchase_time&sortDirection=desc" \ -H "X-API-Key: $OGARNIAI_API_TOKEN" \ -H "Accept: application/json"Get documents from a date range
Section titled “Get documents from a date range”curl -X GET "https://api.ogarni.ai/api/PurchaseDocuments/my?from=2025-01-01&to=2025-01-31" \ -H "X-API-Key: $OGARNIAI_API_TOKEN"Get current month summary
Section titled “Get current month summary”curl -X GET "https://api.ogarni.ai/api/summaries/presets?preset=current-month&granularity=Day" \ -H "X-API-Key: $OGARNIAI_API_TOKEN"List unread notifications
Section titled “List unread notifications”curl -X GET "https://api.ogarni.ai/api/Notifications?isRead=false" \ -H "X-API-Key: $OGARNIAI_API_TOKEN"Python
Section titled “Python”Basic client
Section titled “Basic client”import osimport requests
class OgarniAiClient: def __init__(self): self.token = os.environ["OGARNIAI_API_TOKEN"] self.base_url = "https://api.ogarni.ai" self.headers = { "X-API-Key": self.token, "Accept": "application/json", }
def get(self, endpoint, params=None): response = requests.get( f"{self.base_url}{endpoint}", headers=self.headers, params=params, ) response.raise_for_status() return response.json()
def list_documents(self, from_date=None, to_date=None): return self.get("/api/PurchaseDocuments/my", { "from": from_date, "to": to_date, })
def get_weekly_summary(self): return self.get("/api/weekly-summaries/latest")
def get_categories(self): return self.get("/api/Categories")
def get_current_month_summary(self): return self.get("/api/summaries/presets", { "preset": "current-month", "granularity": "Day", })client = OgarniAiClient()
# Get this month's spendingsummary = client.get_current_month_summary()print(f"Total: {summary['totalAmount']} PLN")
for cat in summary["categoryTotals"]: print(f" {cat['category']}: {cat['totalAmount']} PLN")
# List recent receiptsdocs = client.list_documents()for doc in docs["items"][:5]: print(f"{doc['storeName']}: {doc['totalAmount']} {doc['currency']}")With rate limit handling
Section titled “With rate limit handling”import timeimport requests
def safe_request(client, endpoint, params=None, max_retries=3): for attempt in range(max_retries): try: response = requests.get( f"{client.base_url}{endpoint}", headers=client.headers, params=params, )
# Log remaining rate limit remaining = response.headers.get("X-RateLimit-Remaining") if remaining: print(f"Rate limit remaining: {remaining}")
if response.status_code == 429: retry_after = int(response.headers.get("Retry-After", 60)) print(f"Rate limited, waiting {retry_after}s...") time.sleep(retry_after) continue
response.raise_for_status() return response.json()
except requests.exceptions.RequestException as e: if attempt == max_retries - 1: raise time.sleep(2 ** attempt)
raise Exception("Max retries exceeded")JavaScript / Node.js
Section titled “JavaScript / Node.js”Basic client using fetch
Section titled “Basic client using fetch”const API_TOKEN = process.env.OGARNIAI_API_TOKEN;const BASE_URL = "https://api.ogarni.ai";
async function apiGet(endpoint, params = {}) { const url = new URL(`${BASE_URL}${endpoint}`); Object.entries(params).forEach(([key, value]) => { if (value !== undefined) url.searchParams.set(key, String(value)); });
const response = await fetch(url, { headers: { "X-API-Key": API_TOKEN, "Accept": "application/json", }, });
if (!response.ok) { throw new Error(`API error: ${response.status} ${response.statusText}`); }
return response.json();}
// List recent receiptsconst docs = await apiGet("/api/PurchaseDocuments/my");console.log(`Found ${docs.items.length} documents`);
// Get this month's spendingconst summary = await apiGet("/api/summaries/presets", { preset: "current-month",});console.log(`Total: ${summary.totalAmount} PLN`);
// List categoriesconst categories = await apiGet("/api/Categories");categories.categories.forEach((cat) => { console.log(`${cat.englishName} (${cat.polishName})`);});With axios and rate limit handling
Section titled “With axios and rate limit handling”import axios from "axios";
const client = axios.create({ baseURL: "https://api.ogarni.ai", headers: { "X-API-Key": process.env.OGARNIAI_API_TOKEN, "Accept": "application/json", },});
// Log remaining rate limit on every responseclient.interceptors.response.use((response) => { const remaining = response.headers["x-ratelimit-remaining"]; if (remaining) console.log(`Rate limit remaining: ${remaining}`); return response;});
// Retry on 429client.interceptors.response.use(undefined, async (error) => { if (error.response?.status === 429) { const retryAfter = parseInt(error.response.headers["retry-after"] || "60", 10); console.log(`Rate limited, waiting ${retryAfter}s...`); await new Promise((resolve) => setTimeout(resolve, retryAfter * 1000)); return client.request(error.config); } throw error;});
const { data: summary } = await client.get("/api/weekly-summaries/latest");console.log(summary.summary);