Skip to main content
The Finta API gives you programmatic access to your company’s financial data: transactions and the source accounts and cards behind them, split lines and spreads, journal entries, categories, departments, tags, automation rules, integration status, what the company’s Finta inbox is asking for, financial reports, key metrics such as cash, runway and revenue growth, R&D tax credits, tax filing progress and PDFs, vendor 1099 filing progress, and your team directory, plus the plans Finta offers and their limits, your company’s own plan and what it pays, and how much of each limit it has used. Most endpoints are read-only. Supported writes include: editing one transaction, editing up to 5,000 in one bulk update, creating a manual bank or credit account, adding a standard category template, creating, renaming or deleting a tag, uploading transactions from a bank or card file, the four operations on a team invitation (create, change its access, resend it, revoke it), the three on an automation rule (create, update, delete), starting an integration connection, the two ways to upload a tax PDF (a multipart request or a direct upload URL), and recording an income tax return or a Delaware franchise tax report the company already filed outside Finta. Invoices and departments are in early access. You can also generate PDF, CSV or Excel financial reports with the asynchronous report export API. It returns a job ID to poll and a download link when ready; generating a file does not edit your books.
To work with Finta from Claude or another AI tool, connect the MCP server. It signs in with your Finta account instead of an API key.
You can also create, list, read and edit spreadsheet documents, search authored cells, and permanently delete a document using its current revision. Create blank documents, use financial templates, or supply worksheets with values, formulas, formatting and charts. Read calls require Forecast: View; creation, editing and deletion require Forecast: Manage. PATCH edits cells, formulas, formatting, structure, worksheets and embedded charts in an ordered atomic batch at a known base_revision.

Agent signup

An agent can request signup with only the user’s email through POST /signups, without an API key, company or OAuth grant. The user activates a one-hour email link in their browser and connects the MCP with Allow. The same 202 response is returned for every account state; existing accounts get no email. Follow next_step.message rather than treating success as proof of delivery. Signup is always available through REST and the signed-out MCP sign_up tool. See Agent signup for the flow, privacy, activation, and retry guidance.

Onboard a company

A new company can complete onboarding through the API or MCP: answer the company questions, submit them after confirmation, connect approved banks, follow the first import, and request a ready email. New OAuth and Plaid connections, including Chase and SVB, use the same API endpoints after approval; the user approves on the returned provider or Plaid Hosted Link page. For Plaid reconnects before or during the first import, follow the web get-started instructions in next_step.message, then send an empty-answer onboarding update. OAuth reconnects still use the API. Setup finishes automatically for API-started onboarding. Start with GET /onboarding and follow next_step.message. Saved drafts can resume in the web app, and unchanged answers saved on the web can be replayed through the API. After web bank connections, start_import requires an empty-answer PATCH. A finished web-started import returns finish_in_web: switch to the company named in the message, open the returned URL and choose See dashboard. Until the company is onboarded, other endpoints return 403 onboarding_incomplete, apart from the onboarding exceptions. Onboarding calls are free, and no API or MCP call consumes the monthly allowance before setup is complete.

Get your API key

1

Go to API Keys

Sign in to Finta and go to Settings > API Keys.
2

Create a key

Click Create API key.
3

Copy the key

Copy the key immediately. It starts with finta_ and is only shown once. You cannot retrieve it later.
Each API key is tied to the user who created it and scoped to a single company. There is no company ID parameter; the key already knows which company it belongs to. If you manage multiple companies, create a separate key for each. If you are removed from a company, your key automatically loses access.

Permissions

A key acts as its owner rather than carrying scopes of its own. Company endpoints require the owner to currently hold API access: Manage, plus the permission the endpoint requires (for example Reports: View for reports, key metrics and journal entries, Taxes: View for tax-credit, tax-filing, and 1099 filing reads, Taxes: Manage to upload a tax PDF and record a return filed outside Finta, Transactions: View to read transactions, accounts, cards, and the company’s usage against its limits, Transactions: Manage to edit transactions, including assigning or removing a tag, create a manual account, upload transactions, match or unmatch a transfer, split a transaction or change or remove its split, or read a bulk update job, Accounting setup: View to read automation rules and tags, Accounting setup: Manage to add a category template or create, rename or delete a tag, Billing: View to read the company’s plan and what it pays, the Admin role to create or resend invitations, Team & access: Manage to edit or revoke them, Integrations: Manage and Transactions: Manage to connect an integration, Invoices: Manage and Transactions: Manage to match a deposit to one or more invoices, Reconciliation: View to read account reconciliations and their statement PDFs, or Reconciliation: Manage to reconcile or unreconcile a period or upload a bank statement PDF to attach). Because permissions are read live on every request, granting or revoking one takes effect on the very next call. There is nothing to reissue. See Permissions for the full endpoint-to-permission table and the 403 you get when something is missing. Both onboarding endpoints require Company: Manage and Integrations: Manage, in addition to API access. The shared onboarding service enforces these permissions on reads as well as writes.

Base URL

All requests go to:

Environments

There is no sandbox or test environment. Every request runs against your real company data, and every response reflects live production data. Write requests, such as categorizing a transaction, modify your live books.

Authentication

Company endpoints use your API key in the Authorization header as a Bearer token:
The public signup endpoint is the exception and needs no credential.

Key prefix convention

Every Finta credential is prefixed so it can be recognized at a glance in logs, error messages, and secret scanners. Today there is one credential type and its prefix is finta_. As additional credential or token types are introduced (for example restricted keys or webhook signing secrets), each will have its own distinct prefix that stacks on the brand prefix (e.g. finta_<type>_...). Treat the prefix as load-bearing: do not strip it before sending, and do not assume a missing or unknown prefix is still a Finta credential.

Content type

API endpoint responses are returned as JSON. Generated report files are downloaded from signed URLs returned in those responses. List and JSON report filters are passed as query strings. Most writes accept JSON request bodies. Sheet updates send base_revision and a name and/or operations in a JSON body. Sheet deletion takes base_revision in the query and accepts no body; success is HTTP 204 with no JSON body.

Pagination

List endpoints (/sheets, /sheets/{id}/cells, /accounts, /cards, /transactions, /journal_entries, /parties/merchants, /rules, /taxes, /tax_credits, /forms/1099, and /aggregations/totals) use cursor-based pagination. Responses are wrapped in a list envelope:
Pass limit (default 100, max 500) to control page size, and starting_after with the next_cursor value to fetch the next page. Treat next_cursor as opaque and pass it back unchanged. There is no offset or page-number parameter. The url field carries the canonical path of the collection and is useful for logging and generic pagination helpers. /categories, /departments, /tags, /integrations, and /inbox are list endpoints too, but their result sets are small and bounded, so they always return everything in one response and omit has_more and next_cursor entirely. POST /transactions/{id}/match_invoices returns a list envelope with every invoice on the payment in one response: has_more: false and next_cursor: null. It does not paginate. /team is not a list endpoint at all. It returns a single team document with its own members and invitations arrays and no list envelope, so there is no object: "list", url, or data to read. If you keep a local copy of transactions, GET /transactions also has an incremental sync mode: pass updated_after and it returns only what changed since your last run, including deletions, plus a watermark to sync from next time. See Incremental Sync. GET /forms/1099 also includes complete yearly summaries on every page. Only the year filter scopes them; vendor/status filters and pagination affect individual records. See 1099 Filings for stages, counts, and empty states. GET /taxes likewise includes a summary of every tax year and type on every page, including years with no filing record (not_started). Only year and type scope them. See Tax filings. See Pagination for full parameters and an example fetch-all loop.

Monetary amounts

Financial-resource monetary fields follow two rules:
  1. Integer cents. Monetary values are integers, never floats and never formatted strings. \$499.00 is 49900. \$1,500.00 is 150000. Divide by 100 to get dollars.
  2. _cents suffix. The field name always ends in _cents (e.g. amount_cents, balance_cents, total_cents). If a field name does not end in _cents, it is not a monetary value.
Financial resources have no “summary” or “display” sibling that returns the same amount in dollars or as a string. Generic spreadsheet cell arrays are a scoped exception: they preserve worksheet units, so a cell amount of $20,000 is 20000, not 2000000. Formatting does not convert it to cents. See Sheets. Sign conventions:
  • Income statement: revenue/income amounts are positive, expense amounts are negative. Summing every section’s total_cents yields net income without sign-flipping.
  • Balance sheet: balance_cents carries the natural-sign cumulative balance for that account at the report date.
  • Cash flow: amount_cents is positive for cash inflows and negative for cash outflows.
Tax credit amounts can be null when unknown. Do not convert null to zero or interpret a payroll credit allocation as a refund received. See Tax credits for amount sources and the separate claim and payroll-submission statuses.

Reporting dates and freshness

The notes below describe JSON report reads. File exports can contain month/quarter/year columns, follow the company’s existing calendar/fiscal report settings, and read the books when the worker generates the file. Reports and category totals use exact inclusive calendar dates in America/Los_Angeles (Pacific Time). Use YYYY-MM-DD dates and determine today in Pacific Time, not from the UTC calendar date. Category-grouped income statements, balance sheets, cash flow, and category totals use fast rollups for whole months; and month-aligned ranges ending today use fresh MTD rollups. Other partial-month boundaries, including a midmonth start, read live journal entries and are slower. Full-date category totals previously selected whole months; they now honor the day. Report amounts remain day-exact. Response dates identify the boundaries actually used, and refreshed_at covers the whole answer, including MTD and live portions. Department-grouped income statements read the full range directly and return refreshed_at: null because that report path supplies no freshness timestamp. See Date sources and freshness for the fallback and legacy month rules.

Errors

The Finta API uses conventional HTTP status codes and returns every error in a consistent JSON envelope. Branch on error.type and error.code to handle errors programmatically; treat error.message as human-readable only and do not parse it. Export retrieval is a resource read: it returns HTTP 200 even for a terminal failed job. Inspect status, then its embedded error.code/error.message; those job details are separate from the HTTP error envelope below. See Report Exports.
See Errors for the full list of error codes with resolution steps.

Making your first request

For a company still setting up, begin with GET /onboarding and follow the onboarding guide. GET /company is gated until setup completes. For an onboarded company, verify your API key by pulling its metadata:
The full schema, including all field types and enum values (e.g. the closed set of entity_type values), is in the Retrieve Company reference. The id is included so you can cross-reference the company from other API responses, and as the disambiguator for the planned multi-company-keys feature; the endpoint is a singleton, so there is no GET /v1/company/{id}. To discover income-tax and Delaware franchise-tax workflows, call GET /taxes without filters first, then retrieve a record by its public ID. See Tax filings for the shared income workflow, statuses, and document links. To record a return filed outside Finta, see Tax uploads. The income statement accepts group_by=category (the default) or group_by=department for the . Both return one period with the same date parameters. See income statement grouping for response layouts and department access requirements. From here, try pulling one category total, the top merchants or month-by-month totals behind it, your income statement, key metrics such as runway and burn, or the journal entries behind a report. GET /integrations is another good first call: it takes no parameters and tells you whether the data behind everything else is still flowing. For integrations with a connection method whose connect_via is api, POST /integrations/{key}/connect returns a link a person opens to connect it, or reconnect an OAuth provider. The six supported Plaid banks use Plaid Hosted Link, with a private 30-minute link and no Finta sign-in; Plaid reconnect stays in the web app. GET /team also takes no parameters and returns the company’s members and pending invitations, and POST /team/invitations adds a new one. A pending invitation can then be changed with PATCH /team/invitations/{id}, sent again with POST /team/invitations/{id}/resend, or withdrawn with DELETE /team/invitations/{id}. The company’s categorization automations are readable and writable too: GET /rules lists them, and POST /rules saves a new one, optionally applying it to existing transactions. To understand how journal entries, transactions, aggregations, and reports fit together, see Data Model.