Most APIs work the same way. You read the docs, learn the data model, map your data to their schema, and build the integration. Every endpoint has its own structure. Every structure requires you to understand the domain.

That works — until the domain is something your team doesn't specialize in.

I hit this wall with accounting. Every app that touches money eventually needs invoices, expense tracking, profit reports, receivables. And suddenly you're not building your product anymore — you're maintaining an accounting system on the side.

The problem with domain-specific APIs

The standard answer is “use an accounting API.” And there are good ones. But they all share the same fundamental assumption:

You already understand the domain. Or you spend weeks learning just enough to use the API without breaking things.

POST /api/invoices
POST /api/expenses
POST /api/journal-entries
GET  /api/reports/profit-loss
POST /api/payments
GET  /api/accounts-receivable

Each endpoint has its own schema. Each schema requires you to know what a journal entry is, how accounts map, what “balanced” means, and how receivables work. You're not just integrating — you're learning accounting to use the API correctly.

For a team building a CRM, a field service app, or a POS system, that's a massive tax on development time. You don't want to become accounting experts. You just want to know: did this customer pay? How much profit did we make? Send this person an invoice.

What if the API didn't require structure at all — just intent?

While building MarathonBooks, we noticed something. Our users — small business owners — never think in accounting terms. They don't say “create a journal entry debiting accounts receivable and crediting revenue.” They say:

“Got paid $500 from John for detailing.”

And our system figures out the rest. It determines the intent, identifies the accounts, creates a balanced entry, and updates the books. The user never touches a chart of accounts.

We'd built this for humans talking to the app via text messages and DMs. Then we realized: why should an API be any different?

So we built one endpoint:

POST /api/v1/quickcapture

That's it. One endpoint for everything.

How it works

You send what happened. The system determines the action and handles the accounting.

Plain text — when that's all you have:

{
  "text": "Send $500 invoice to Mike for landscaping"
}

Structured JSON — when you want precision:

{
  "type": "invoice",
  "amount": 500,
  "customer": "Mike",
  "description": "landscaping"
}

Both produce the same result:

{
  "success": true,
  "intent": "create_invoice_draft",
  "reply": "Invoice INV-0012 created for Mike — $500.00 for landscaping.",
  "link": {
    "url": "https://books.marathonbooks.app/i/a1b2c3...",
    "label": "View invoice"
  }
}

The API handles expenses, income, invoices, receivables queries, profit reports, loans — all through the same endpoint. The payload describes what happened. The system figures out the accounting.

Control when you need it

“But what about predictability?” — fair question. An intent-driven API sounds great until you need deterministic behavior in production.

So we added control layers. All optional. Use them when you need them, ignore them when you don't.

Explicit intent — skip AI classification entirely:

{
  "intent": "capture_expense",
  "text": "Paid $120 for supplies"
}

Strict mode — require explicit intent, no guessing:

{
  "mode": "strict",
  "intent": "create_invoice_draft",
  "text": "Invoice Mike $500 for landscaping"
}

Dry run — preview what would happen without executing:

{
  "dry_run": true,
  "text": "John paid me $500"
}

Returns the detected intent and parameters without creating any records. You can validate before committing.

Idempotency — prevent duplicates:

{
  "idempotency_key": "txn_abc123",
  "text": "Paid $120 for supplies"
}

The spectrum goes from full AI inference to fully deterministic. You start loose and tighten as your integration matures.

Any language in, structured data out

Here's something we didn't plan for but turned out to be a major advantage.

Most APIs assume English. This one doesn't.

Because the API accepts natural language, it inherently works in any language. The same endpoint processes:

"Paid $120 for supplies at Home Depot"

"Pagué $120 por materiales en Home Depot"

"Paguei $120 por materiais na Home Depot"

Same structured output every time. No translation layer. No localization logic on the developer's side.

For apps serving multilingual markets — and for the massive Spanish-speaking small business market in the US — this removes an entire layer of engineering work.

What this actually changes

The traditional integration model looks like this:

  1. Read the API docs
  2. Learn the accounting data model
  3. Map your data to their schema
  4. Build transformation logic
  5. Handle edge cases
  6. Maintain the mapping as both sides evolve

The intent-driven model:

  1. Send what happened
  2. Get structured results

That's not a small difference. It fundamentally changes who can integrate financial features and how fast they can do it.

There's no chart of accounts to design, no journal entries to construct, no mapping layer to maintain.

A solo developer building a field service app can add invoicing in an afternoon. A POS system can pipe transactions without modeling a chart of accounts. An internal tool can generate profit reports without knowing what “retained earnings” means.

Real-world use

I tested this approach in a legacy DMV services app — a system that was never designed for accounting. Using the QuickCapture API, I was able to:

  • Send invoices directly from the existing workflow
  • Automatically record income when services were marked as paid
  • Surface a simple business health view on the dashboard

Without building any accounting logic into that app. The DMV system just sends business events as text. QuickCapture handles the rest.

That's when I knew this wasn't just a nice API design — it was a fundamentally different way to add financial capabilities to existing software.

The deeper shift

This is part of a broader pattern I think we'll see more of in APIs:

From endpoints to intent. Instead of mapping your system's actions to an API's resource model, you describe what happened and the API determines the appropriate action.

From structure-first to meaning-first. Traditional APIs require you to structure data before sending it. Intent-driven APIs accept data in the form it naturally takes — messy text, partial information, mixed languages — and create structure on the other side.

From integration to conversation. The same system that processes API requests also handles text messages, Instagram DMs, and WhatsApp messages. The API is just another channel. A developer and a contractor texting from a job site are both sending business events — through different interfaces, into the same engine.

What we didn't simplify

It's worth being clear about what's underneath. The API produces real double-entry bookkeeping. Every transaction creates balanced journal entries. The ledger is immutable — corrections happen through reversals, not edits. Reports are audit-ready.

We didn't simplify the accounting. We simplified the interface to it.

That distinction matters. Simple interfaces on top of rigorous systems is the whole game. You want your users (or your API consumers) to never think about debits and credits — but you want their accountant to find clean books when tax season comes.

Try it

If you're building something that touches money and you're tired of modeling accounting data:

The API accepts plain text or structured JSON. Send what happened — it handles the rest. Developer docs here.

Or if you just want to see what it feels like, visit marathonbooks.app and type something into the QuickCapture box. No signup required. You're already using the product before you even sign up.


We didn't simplify accounting APIs. We removed the need to understand accounting to use them. And I think that's where APIs are headed — not just in accounting, but everywhere domain complexity lives behind an endpoint.