Skip to main content

Transactions

Transactions are the core data stream that powers Ozzie's spending analysis, plan tracking, and personalized recommendations. Ozzie uses GPT-4o to parse natural language descriptions, receipt images (OCR), bank statement PDFs, and CSV spreadsheets into structured, categorized transaction records.

A single submission can result in multiple transactions β€” for example, a text message saying "coffee $5 and lunch $15" will produce two separate transaction objects.


The Transaction Object​

{
"id": "ozz_txn_01HX9Q5NRWBF3KMZP4VC7YDLA",
"user_id": "ozz_usr_01HX9KZMR4P5JQNBVT7YCW3DE",
"amount_cents": 4500,
"currency": "USD",
"category": "food",
"envelope": "Daily Living",
"description": "Grocery shopping at Extra Supermarket",
"transaction_date": "2025-05-05",
"source": "api_text",
"ai_confidence": 0.97,
"created_at": "2025-05-05T14:34:00Z"
}

Transaction Object Fields​

FieldTypeDescription
idstringOzzie-generated UUID for this transaction
user_idstringThe Ozzie user this transaction belongs to
amount_centsintegerTransaction amount in cents (e.g., 4500 = $45.00)
currencystringISO 4217 currency code (e.g., "USD", "BRL", "EUR")
categorystringSpending category (see table below)
envelopestringBudget envelope this transaction belongs to (see table below)
descriptionstringAI-generated human-readable description of the transaction
transaction_datestringTransaction date in YYYY-MM-DD format
sourcestringHow the transaction was submitted (see table below)
ai_confidencefloatAI parsing confidence score from 0.0 to 1.0
created_atstringISO 8601 UTC timestamp of when the record was created in Ozzie

category Values​

ValueDescription
foodGrocery stores, restaurants, cafes, food delivery
transportGas, public transit, rideshare apps, parking, tolls
housingRent, mortgage, home insurance, renovations
utilitiesElectricity, water, internet, phone bill
healthPharmacy, medical appointments, gym, health insurance
entertainmentStreaming, cinema, games, events
educationTuition, books, courses, educational subscriptions
clothingClothes, shoes, accessories
incomeSalary, freelance payment, extra income, reimbursements
otherAnything that does not fit the categories above

envelope Values​

Ozzie groups each transaction into one of six budget envelopes. The envelope is derived automatically from the category and is always present in the response.

EnvelopeIncluded categories
Billshousing, utilities β€” fixed monthly bills
Daily Livingfood, transport β€” everyday spending
Health & Wellnesshealth β€” health, pharmacy, gym
Lifestyleentertainment, education, clothing β€” lifestyle
Peopleother β€” gifts, family, social events
Your Futureincome β€” salary, extra income, savings

Use the envelope field to build spending summaries grouped by area of spending without any extra mapping on the client side.

source Values​

ValueDescription
whatsapp_textText message received via WhatsApp
whatsapp_imageImage (receipt/screenshot) received via WhatsApp
api_textText submitted via REST API
api_imageImage submitted via REST API (base64)
api_pdfText extracted from PDF submitted via REST API
api_spreadsheetCSV data submitted via REST API

POST /v1/users/{user_id}/transactions​

Submit one or more transactions for parsing. Ozzie uses GPT-4o to extract structured transaction data from the provided content. The type field determines how the content is interpreted.

Path Parameters​

ParameterDescription
user_idThe Ozzie UUID of the user or external:{external_user_id}

Request Body β€” Discriminated Union by type​

The shape of the request body depends on the type field. All types share the language field.

type: "text"​

Submit a natural language description of one or more transactions.

FieldTypeRequiredDescription
typestringYesMust be "text"
contentstringYesNatural language transaction description
languagestringNoLanguage hint for parsing: "en" | "pt" | "es". Default: user's language.
{
"type": "text",
"content": "Spent $45 at the grocery store and $12 on the subway",
"language": "en"
}

type: "image"​

Submit a receipt, screenshot, or purchase photo as a base64-encoded image. Ozzie performs OCR and analyzes the result.

FieldTypeRequiredDescription
typestringYesMust be "image"
contentstringYesBase64-encoded image data
mime_typestringYesImage MIME type: "image/jpeg" | "image/png" | "image/webp"
languagestringNoLanguage hint for OCR and parsing
{
"type": "image",
"content": "/9j/4AAQSkZJRgABAQEASABIAAD...",
"mime_type": "image/jpeg",
"language": "en"
}

type: "pdf"​

Submit the extracted text content from a bank statement or PDF receipt. Extract the text from the PDF on your side before submitting.

FieldTypeRequiredDescription
typestringYesMust be "pdf"
contentstringYesPlain text extracted from the PDF
languagestringNoLanguage hint for parsing
{
"type": "pdf",
"content": "BANK STATEMENT\nDate: 2025-05-01\nMerchant: Amazon.com\nAmount: -$89.99\nDate: 2025-05-02\nMerchant: Netflix\nAmount: -$15.99",
"language": "en"
}

type: "spreadsheet"​

Submit CSV-formatted transaction data. Include a header row. Ozzie normalizes column names flexibly (e.g., Date / date / transaction_date are all recognized).

FieldTypeRequiredDescription
typestringYesMust be "spreadsheet"
contentstringYesCSV string with header row
languagestringNoLanguage hint for parsing
{
"type": "spreadsheet",
"content": "date,description,amount\n2025-05-01,Grocery Store,45.00\n2025-05-02,Subway,12.00\n2025-05-03,Netflix,15.99",
"language": "en"
}

Response​

Returns a transaction_list object containing all parsed transactions from the submission. A single submission can produce one or many transactions.

{
"object": "transaction_list",
"data": {
"transactions": [ ... ]
}
}

Errors​

CodeHTTPWhen
NOT_FOUND404The user_id does not exist
VALIDATION_ERROR400Required fields missing, invalid type, or unsupported mime_type
UNAUTHORIZED401Missing or invalid credentials

Examples β€” Text Input​

curl -X POST \
https://channel.ozzieapp.com/v1/users/ozz_usr_01HX9KZMR4P5JQNBVT7YCW3DE/transactions \
-H "Authorization: Bearer czJjbGllbnQ6czJzZWNyZXQ=" \
-H "Content-Type: application/json" \
-d '{
"type": "text",
"content": "Spent $45 at the grocery store and $12 on the subway",
"language": "en"
}'

Example Response β€” 2 transactions parsed from a text message (201 Created):

{
"object": "transaction_list",
"data": {
"transactions": [
{
"id": "ozz_txn_01HX9Q5NRWBF3KMZP4VC7YDLA",
"user_id": "ozz_usr_01HX9KZMR4P5JQNBVT7YCW3DE",
"amount_cents": 4500,
"currency": "USD",
"category": "food",
"description": "Grocery shopping",
"transaction_date": "2025-05-05",
"source": "api_text",
"ai_confidence": 0.97,
"created_at": "2025-05-05T14:34:00Z"
},
{
"id": "ozz_txn_01HX9Q5NRWBF3KMZP4VC7YDLB",
"user_id": "ozz_usr_01HX9KZMR4P5JQNBVT7YCW3DE",
"amount_cents": 1200,
"currency": "USD",
"category": "transport",
"description": "Subway fare",
"transaction_date": "2025-05-05",
"source": "api_text",
"ai_confidence": 0.95,
"created_at": "2025-05-05T14:34:00Z"
}
]
}
}
Multiple transactions per submission

Ozzie intentionally parses all distinct transactions from a single input. A grocery stop plus a coffee stop in the same message will produce two separate transaction records. This matches real-world usage where users describe their day in a single message.

Image submission tip

For receipt images, JPEG and PNG work well. Ensure the image is under 10MB before base64 encoding. Very blurry or rotated images may result in lower ai_confidence scores (below 0.7). Consider prompting the user to retake the photo if confidence is low.


GET /v1/users/{user_id}/transactions​

Returns a paginated list of a user's transactions, ordered by transaction_date descending (most recent first).

Path Parameters​

ParameterDescription
user_idThe Ozzie UUID of the user or external:{external_user_id}

Query Parameters​

ParameterTypeDefaultDescription
limitinteger50Number of transactions per page. Maximum 200.
cursorstringβ€”ISO 8601 datetime cursor for pagination. Returns transactions older than this timestamp.
fromstringβ€”Filter: include transactions from this date (YYYY-MM-DD).
tostringβ€”Filter: include transactions up to this date (YYYY-MM-DD).
categorystringβ€”Filter by category (e.g., food, transport). Comma-separate for multiple: food,transport.

Response​

{
"object": "list",
"data": {
"transactions": [ ... ],
"has_more": true,
"next_cursor": "2025-04-28T09:15:00Z",
"total_count": 142
}
}

Errors​

CodeHTTPWhen
NOT_FOUND404The user_id does not exist
VALIDATION_ERROR400Invalid from/to date format, or limit out of range
UNAUTHORIZED401Missing or invalid credentials

Examples​

# Transactions for May 2025
curl "https://channel.ozzieapp.com/v1/users/ozz_usr_01HX9KZMR4P5JQNBVT7YCW3DE/transactions?from=2025-05-01&to=2025-05-31&limit=100" \
-H "Authorization: Bearer czJjbGllbnQ6czJzZWNyZXQ="

# Next page using cursor
curl "https://channel.ozzieapp.com/v1/users/ozz_usr_01HX9KZMR4P5JQNBVT7YCW3DE/transactions?from=2025-05-01&to=2025-05-31&limit=100&cursor=2025-05-20T10:00:00Z" \
-H "Authorization: Bearer czJjbGllbnQ6czJzZWNyZXQ="
Amount is always in cents

amount_cents is always an integer in the smallest monetary unit (cents for USD/BRL, etc.). Divide by 100 to display dollar values. This avoids floating-point precision issues.

Interpreting ai_confidence

Scores above 0.85 indicate high confidence in the parsed category and amount. Scores between 0.6 and 0.85 may benefit from user confirmation. Scores below 0.6 suggest the input was ambiguous β€” consider prompting the user to clarify. Ozzie never silently discards low-confidence transactions; they are always returned.