My year & tax report
Per-account month coverage, a Schedule C view with real IRS line numbers, and a cash-basis balance snapshot, built from your own bank/card statement documents.
Two read APIs, both scoped to your org and a calendar year, both computed fresh on every call from your documents' already-stored extraction results. Nothing is pre-aggregated or cached, so a corrected category or a newly uploaded statement is reflected immediately.
GET /v1/year-overview is always free, on every plan. The tax report, its export, and 1099 entries are part of the bookkeeping product: locked on Free, unlocked by an active Catch-Up purchase for the exact tax year asked about, or a live Autopilot/Business subscription for the current calendar year (402 TAX_REPORT_LOCKED otherwise). This is the same rule the app dashboard and MCP server enforce, not just this API.
Card balances use positive amounts for debt and negative amounts for credit. Balance snapshots group formatted account numbers by institution and account type. Invoices count as cash expenses only through a matched bank payment or a recorded payment_date. Unpaid invoices appear with a review_reason. Balance rows retain their source currency; only USD balances count in USD totals. Non-USD amounts stay out of USD totals and appear in uncategorized_transactions with currency and review_reason. The accountant CSV includes settled income with signed amounts, categories, document_id and row_index.
Readable statement rows remain in the report when another row is unreadable. Unreadable amounts are null in uncategorized_transactions, with a review_reason, and blank in the accountant CSV.
Unknown transaction dates remain empty and need a date before they count in any tax year. Upload dates are never used as transaction dates.
Create received forms with POST /v1/form-1099. Required fields are an integer tax_year from 2000 through 2100,form_type of NEC or K, and a numeric amountfrom 0 through 999999999999 dollars. The optional payer_nameaccepts a string or null. Invalid fields return 400 before tax-year access is checked.
GET /v1/year-overview
Groups your bank_statement documents by account (as extracted, Arkrel has no separate "client" concept), and reports which months are covered vs. missing per account, reusing the exact same continuity engine POST /v1/statement-sets uses. Also totals income vs. spending by category and suggests one next step.
{
"year": 2026,
"accounts": [
{
"account_number": "****4471",
"label": "Checking ending 4471",
"months": [
{ "month": "2026-01", "label": "Jan 2026", "covered": true, "document_id": "doc_jan" },
{ "month": "2026-02", "label": "Feb 2026", "covered": false, "document_id": null }
],
"months_covered": 1,
"months_expected": 2,
"document_ids": ["doc_jan"],
"findings": []
}
],
"months_covered": 1,
"months_expected": 2,
"income_total": 5000,
"spending_total": 120,
"spending_by_category": [{ "category": "advertising", "label": "Advertising", "total": 120 }],
"needs_review_documents": 0,
"failed_documents": 0,
"processing_documents": 0,
"uncategorized_transactions": 0,
"open_items": 1,
"next_step": { "message": "Upload your Feb 2026 checking ending 4471 statement.", "action": "upload", "document_id": null, "account_number": "4471", "month": "2026-02" }
}GET /v1/tax-report
A profit-and-loss statement, a Schedule C (Form 1040) view (every deductible category cites the real IRS line, e.g. line 8 "Advertising" or line 24b "Deductible meals"), the list of likely deductible expenses behind each line, and a cash-basis account-balances snapshot.
total_expenses/net_profit: the Cash P&L view, the full cash amount spent in every category. A refund or credit in the same category nets against the charge it reverses (a $100 charge and a $40 refund count as $60), rather than adding to the total; a refund's owndeductible_expensesrow shows a negative amount so the direction it actually moved is never lost.schedule_c_lines: only lines with a nonzero total, sorted by line number. A category with a deductible-percentage limit (currently only meals, at 50% under the Instructions for Schedule C, line 24b, and IRC section 274(n)(1)) reports the deductible amount intotaland the full cash amount infull_amount; every other line hasfull_amount: nullbecause it equalstotal.schedule_c_expenses/schedule_c_net_profit: the Schedule C view, the sum ofschedule_c_lines(with any deductible-percentage limits already applied) and the resulting net profit. This differs from the Cash P&L totals whenever a limited category, such as meals, has spend.uncategorized_transactions: not confidently matched to a category: excluded from every total until categorized (see the PATCH below).confidence_label(on everydeductible_expenses/uncategorized_transactionsrow): the ready-to-render label. "You set this" for a correction you saved yourself, "Standard rule" for a deterministic keyword-rule match, and a percentage ("Category confidence: 20%") only for a genuine low-confidence guess. Always show this verbatim; a rule match or a saved correction is never a probabilistic guess, so never recompute a percentage fromconfidenceyourself.excluded_transactions: transfers between your own accounts personal (non-deductible) spending, and asset or liability movements: also excluded from every total, shown separately so nothing you paid is silently dropped.equipment_needs_review: a large one-time purchase (often equipment needing depreciation under Schedule C line 13 / Form 4562, unless it qualifies for the $2,500 de minimis safe harbor) held out of every deductible total until you resolve how it should be treated.likely_needs_1099: vendors you paid $600 or more (2025 and earlier) or $2,000 or more (2026 onward, One Big Beautiful Bill Act) in a services category, and so may need a Form 1099-NEC issued to them. Payment platforms, marketplaces, and card processors (Upwork, Fiverr, PayPal, Venmo, Stripe, Square, and similar) never appear here: the Instructions for Forms 1099-MISC and 1099-NEC (irs.gov/instructions/i1099mec, "Form 1099-K") put the reporting duty for those payments on the payment settlement entity, on Form 1099-K, not on you.form_1099: compares the 1099-NEC/1099-K amounts you enter (received as income) againstgross_receipts.differenceisnulluntilentrieshas at least one form: before that there's nothing to compare yet, never a difference computed against zero.balance_sheet: each account's latest statement closing balance at or before December 31: a cash-basis snapshot, not a formal (accrual) balance sheet. Each line carries the statement's own detectedaccount_type("bank","credit_card", ornullwhen not determinable).cash_totalandcredit_card_owedare separate sums, never combined: a bank account's balance is cash you have, a credit card's is money you owe. A line withaccount_type: nullstill appears inlines, but counts toward neither total.
{
"year": 2026,
"income_total": 5000,
"total_expenses": 120,
"net_profit": 4880,
"schedule_c_expenses": 120,
"schedule_c_net_profit": 4880,
"schedule_c_lines": [
{ "category": "advertising", "label": "Advertising", "line": "8", "line_label": "Advertising", "total": 120, "full_amount": null, "note": null }
],
"deductible_expenses": [
{ "document_id": "doc_jan", "row_index": 3, "date": "2026-01-08", "description": "GOOGLE ADS 48213",
"amount": 120, "category": "advertising", "category_label": "Advertising", "overridden": false,
"confidence": 0.85, "confidence_label": "Standard rule", "reconciled": true, "source_page": null }
],
"uncategorized_transactions": [],
"excluded_transactions": [],
"equipment_needs_review": [],
"likely_needs_1099": [
{ "payee_label": "SMITH LAW OFFICE", "total": 2400, "transaction_count": 6, "threshold": 600 }
],
"form_1099": {
"tax_year": 2026, "entries": [{ "id": "f1099_1", "tax_year": 2026, "form_type": "NEC", "payer_name": "Acme Co", "amount": 3000 }],
"total_reported": 3000, "gross_receipts": 5000, "difference": 2000,
"citation": "Schedule C asks directly whether you made payments requiring a Form 1099."
},
"balance_sheet": {
"as_of_year_end": 2026,
"lines": [
{ "account_number": "****4471", "label": "Checking ending 4471", "as_of_date": "2026-01-31", "closing_balance": 5380, "document_id": "doc_jan", "account_type": "bank" },
{ "account_number": "****9902", "label": "Credit card ending 9902", "as_of_date": "2026-01-28", "closing_balance": 420.75, "document_id": "doc_card_jan", "account_type": "credit_card" }
],
"cash_total": 5380,
"credit_card_owed": 420.75,
"note": "Cash-basis snapshot from each account's most recent statement closing balance at or before December 31."
}
}GET /v1/tax-report/export
?format=csv (the categorized deductible-expense list), ?format=accountant_csv (every transaction, income and expense, including anything still needing review and any payees who may need a 1099, built for handing to a preparer), or ?format=pdf (the full report as a document).
PATCH /v1/tax-report/transactions/{document_id}/{row_index}
Corrects one transaction's category. Requires a write-scoped API key. row_index is the 0-based index into that document's own transactions table. Your correction always wins over the auto-suggested category on every future read, until you change it again.
PATCH /v1/tax-report/transactions/doc_jan/3 HTTP/1.1
Authorization: Bearer sk_live_...
Content-Type: application/json
{ "category": "office_expense" }Share with your accountant
From the app (/app/tax-report), create a secure, expiring, read-only link to your report: no account or login required to view it. The link expires after 30 days, or revoke it anytime; creating a new link for the same tax year automatically revokes the previous one. There is no API to create this link programmatically by design: it's a deliberate, human action from the dashboard. Every public view and export checks access to that tax year again. If a refund or AppSumo revocation removes access, both GET /share/api/{token} and GET /share/api/{token}/export return402 TAX_REPORT_LOCKED immediately.