Python SDK: Expenses
Use keito 0.3.0 or later and an initialized client. Discover the project’s active category before creating an expense; see category lookup.
Create and read
from keito.core.request_options import RequestOptions
expense = client.expenses.create(
project_id=project_id,
expense_category_id=category_id,
spent_date="2026-10-30",
total_cost=24.50,
notes="Receipt imported from my application",
source="api",
request_options=RequestOptions(
additional_headers={"Idempotency-Key": "receipt-import-unique-001"}
),
)
saved = client.expenses.get(expense.id)
print(saved.total_cost, saved.currency)
Use total_cost for amount-based categories or units for a configured per-unit category. The category supplies the unit price; unit_price is not a create argument. Persist the returned ID before uploading a file.
Receipt files
with open("/path/to/receipt.pdf", "rb") as receipt:
client.expenses.upload_receipt(
expense.id,
file=receipt,
filename="receipt.pdf",
content_type="application/pdf",
)
contents = client.expenses.download_receipt(expense.id)
print(len(contents))
# Only when the user explicitly wants to remove the receipt:
# client.expenses.delete_receipt(expense.id)
The file must be nonempty and at most 9 MiB. PDF, JPEG, PNG, GIF, WebP, HEIC, HEIF and TIFF are supported. Uploading replaces the current receipt. Multipart uploads are not automatically replayed; keep the expense ID and retry deliberately. Invoice attachment selection is a separate choice.
Iterate and update
for row in client.expenses.list(project_id=project_id, source="api"):
print(row.id, row.total_cost)
client.expenses.update(expense.id, notes="Reviewed receipt")
# Explicit deletion only:
# client.expenses.delete(expense.id)
List returns a lazy iterator with no .data attribute. With AsyncKeito, use async for row in client.expenses.list(...) and await item reads/mutations. Approved, billed or locked expenses and submitted/approved timesheet weeks may prevent changes. See the REST contract for the complete policy and refund/classification endpoints.