Finocket's developer platform lets your own products, scripts and AI tools work your books over a versioned REST API. Everything lives under Developers & API, which you reach from Settings → Developers & API — it is no longer a row in the product menu. Products, scoped API keys, OAuth clients, webhooks, payments onboarding, request logs and a live API reference all live there. Every call is workspace-scoped by row-level security.
How do I get started with the API?
- Open Developers — the overview shows your keys, webhooks and recent API activity at a glance.
- Register a product under Developers → Products — a named container for what you're building (your app, an internal script, an AI agent). Keys and webhooks hang off it.
- Create an API key under Developers → API Keys. Pick live or test mode and tick exactly the scopes it needs — there are 17, from
invoices:writetoreports:read— nothing more. - Copy the key immediately. It is shown once, at creation, then never again. Send it as
Authorization: Bearer dmfy_live_…on every request to/api/v1/*.
Writes are idempotent where it matters: creates dedupe on your own external_id or an Idempotency-Key header, so a retried request never acts twice.
What can the API do?
The /api/v1 surface covers the whole business: clients and their ledgers, invoices (create, send, remind, PDF, payments, cancel), payments and refunds, payment links, subscriptions, expenses, items and live stock, sales and purchase orders, CRM (contacts, deals, pipelines, tasks), consent records, partner commissions — plus read-only reports: trial balance, P&L, balance sheet, ageing, GSTR-1/3B/2B/9, day book, Tally XML and more.
Two of those reads are worth knowing the shape of before you build against them. Email engagement returns opens and clicks folded into the same day-by-hour grid the report screen draws, so a dashboard you build yourself cannot disagree with the screen. Opens arrive in a field named opens_unverified, and the reason travels with them in the response rather than living only in our help pages: Apple Mail and company mail scanners fetch a tracking pixel without anyone reading the message, so an open is a hint and a click is the fact. The busiest hour is described, not recommended. No IP address is returned, because none is stored, and nothing is per-recipient — it is an aggregate.
Connected credentials answers which providers a workspace has connected, how each one was connected, whether it is verified and when it was last checked. It never returns a key, a fragment of one, its length or a fingerprint — there is no argument for another workspace, and one with nothing connected answers exactly like one that does not exist. Running several companies? Send X-Company-Id to pick one per request, or pin the key to a company at creation.
How do webhooks work, and how do I verify them?
- Register an HTTPS endpoint under Developers → Webhooks and pick events —
invoice.created,payment.recorded,stock.lowand more, or all. - Finocket POSTs JSON with the event name, timestamp and data. Failed deliveries retry with exponential backoff (up to six attempts).
- Verify every delivery: read the
X-Demystify-Signatureheader (t=<timestamp>,v1=<signature>), recomputeHMAC-SHA256(secret, timestamp + "." + rawBody)with your endpoint's secret, compare in constant time, and reject stale timestamps to block replays.
Events fire however the record was written — through the API, in Finocket itself, on a phone that was offline at the time, from a bank reconciliation, from the till, or when a payment provider confirms one. So a system you have connected learns that a customer paid even when your accounts team typed it in here, which is what lets it lift a suspension on its own. A payment waiting on an approval sends nothing until it is approved; a rejected one never sends.
Developers → Webhooks also shows Recent deliveries: every event handed over, whether it arrived, what the endpoint answered, and how many attempts it took. A delivery that keeps failing stops retrying after about six hours — if the other system was down longer than that, press Resend on the row once it is back.
When should I use OAuth instead of an API key?
When a whole product — not one script — needs access. Create an OAuth2 client under Developers → OAuth Clients; it uses the client-credentials grant: exchange client id and secret at POST /api/oauth/token for a short-lived bearer token carrying only the scopes you granted. Revoke the client and its tokens stop working.
Can I collect payments for my own customers?
Yes — Developers → Payments onboards sub-merchants under the aggregator model (powered by Razorpay). Register a sub-merchant, and money settles directly to their bank account — it never passes through your books or Finocket's. You get payment links and status webhooks per sub-merchant.
Where do I debug and explore?
- Developers → Request Logs — every API request and webhook delivery attempt, with status and timing.
- Developers → API Reference — a live Swagger playground: authorize with your key and fire real requests from the browser. The OpenAPI spec is at
/api/v1/openapi.json. - Developers → API Docs — the guided walkthrough, including MCP setup so AI agents (like Claude) can use your books as tools.
- Developers → Environment — the reference list of configuration names the platform uses (names only, never values).
On the phone and tablet apps these pages open in your browser rather than inside Finocket. They are built for a keyboard and a wide screen — keys, webhook URLs and request logs — so the app hands them to the browser instead of squeezing them in.
What are the inbound lead-capture webhooks?
Alongside the outbound webhooks above, Finocket exposes inbound endpoints that turn provider events into leads: telephony (calls and missed calls), inbound SMS, inbound email and WhatsApp. Each endpoint stays switched off — answering “not found” — until its token is configured; the Developers page lists the URL per channel to paste into your provider’s dashboard. See Inbox & capture for the user-side story.
What can the AI/MCP tools reach?
The MCP tool registry covers your whole business — books, GST, invoicing, inventory — and, since the growth release, the CRM chain too: leads, accounts, marketing campaigns, campaign ROI, lead funnel by source, partner earnings, team activity and activation history, plus commission-rule management. It also reads open work-in-progress per work order, and your GST notice register with how far each reply has got. Same permissions as the signed-in user; every write proposes before it commits.
For outreach audits there is also list_attested_sends: the messages that went out on consent you declared rather than consent a contact recorded themselves. It answers the first question any data-protection review asks — which sends relied on an unverified claim — without reconstructing it from the message log by hand. Blocked sends on a lapsed declaration are included, because those are exactly what you want to see.
What the tools deliberately cannot do
Some things are reachable in the app and are not exposed as tools, on purpose — because a tool call has no confirm card and no named human behind it:
- Approving anything an assistant drafted. Growth-agent campaigns and GST notice replies are approved in the app, by a person. A tool would put a model on both sides of that review.
- Changing how much an assistant may do unattended. The autonomy setting is not tool-reachable, so an agent cannot widen its own limits.
- Committing a Tally import, or undoing a completed action. Both are large writes that exist behind a review step. Exporting to Tally is exposed, because it changes nothing.
- Your personal tax figures. API keys carry business scopes, and there is no tax scope — so your rent, premiums and investment rows are never reachable with a key issued for the books. Ask Mysty inside the app instead.
Nothing here files a return, moves money, or sends a message without the same consent and quiet-hours checks the rest of Finocket applies.
Related: Modules & plans, Usage & activity.
Why doesn't my counter-sales total match the till's Z-report?
It should, and now it does — but only if you add up the right column. A refund at the counter is a credit note, and a credit note carries a positive total, because that is what the document says: it is a real credit for a real amount. It also carries the terminal of the bill it reverses, so it appears in /v1/pos/sales alongside the sales.
So every row carries two fields you should read together. direction is "sale" or "return", and signed_total is the same money with that direction applied — negative for a return. Sum signed_total, never total. Summing total adds refunds to takings instead of subtracting them, so a day is overstated by twice what you refunded.
Cancelled bills are not in the list at all. An exchange that fails part-way cancels its credit note rather than deleting it, so the trail survives — but a reversal that never happened is not money, on this list or on the Z-report. Drafts are excluded for the same reason: nothing was rung up.
Filter by from, to and terminal_id for a date range at one till. For a single register session, take the rows whose cash_session_id is that session: their signed_total adds up to exactly the net figure the Z-report shows for it. The two are built from one definition of what a counter sale is, so they cannot drift apart.
My key was refused. Do I need to upgrade?
Not necessarily, and the response tells you which of three things happened rather than making you guess. All three are a 403, and they need three different fixes.
- The key was never given that scope. The message names the missing scope. Fix it by issuing a new key with the right scopes ticked — scopes cannot be added to a key after it is made.
- The plan no longer includes that area. The error code is
plan_upgrade_requiredand the message names the area. The key is fine; the workspace moved to a plan that does not carry it. Changing plan restores it. - An administrator switched that area off for the workspace. The code is the plain
forbiddenand the message says so: no plan change lifts this. Buying a bigger plan will not help, and we will not suggest it. Ask whoever administers the workspace to switch the area back on.
A workspace owner simply hiding an area from their own menu does not refuse your key. Tidying a menu and cutting off an integration are different acts, and only the second one is deliberate.
The AI/MCP tools answer the same way, in the same three flavours, for the same reasons — so a tool call and a REST call cannot disagree about whether you are allowed in.
Paise or rupees?
Money fields are not all the same unit, and getting it backwards overstates an amount a hundredfold. The reference states, in one place, which fields are whole paise and which are rupees — check it before you write the first integer.
The reference is checked against the API itself on every build, address by address and call by call. A call shipped without documentation, or documented without being shipped, stops the build rather than reaching you.
