How Economico's books fit together

Economico keeps one business’s books as a permanent history of recorded facts. Your application sends commands over REST, MCP or the CLI. Accepted commands record events and update the books; reads and reports let you inspect the result. The same business and permission checks apply across these surfaces.

Start with this page to understand the model, the direct API walkthrough to make a call, and the complete API reference to look up an exact request. Agents should use the agent concepts guide.

The path from evidence to a number

Source document + observed facts
              ↓
           Command → Command receipt
              ↓
       Immutable event history
              ↓
    Documents, records and postings
              ↓
           Reports

Not every command posts money. Creating a customer adds a party. Receiving a source document preserves its bytes. Recording a contract’s billing phase can create a claim and balanced postings. Each command’s schema and result say what it accepts and produces.

Business: whose books you are using

A business has its own history, members, documents and ledgers. Select it with X-Economico-Business: <slug> on business REST requests. There is no global “current business” to set once for an API connection.

A slug identifies the business; it grants no access. The caller’s effective permissions combine live membership, the application’s grant and the token’s ceiling. GET /v1/catalog/permissions describes that intersection. GET /v1/businesses lists the businesses a connection can select.

Use a disposable sandbox for integration practice. A demo company contains fictional records and limits what you may do. Never run these examples against Economico’s own business, slug economico.

Command: a request to change the books

A command names an intent such as parties.create, documents.receive or contracts.record. Send it to POST /v1/commands with its typed input, a stable idempotency_key and effective_at. Describe it first through GET /v1/catalog/commands/{name}. A command is a request, not a historical fact; it can be refused without changing the books.

One accepted command is applied in one transaction. Its command receipt contains commandId, replayed, result and the events it emitted. The result may contain a record id or document id needed by the next command. Use that returned id; do not construct a replacement from a name.

The idempotency key identifies the same intent within that business. Retrying the same command, input and source document with that key returns its original command receipt. Changing those under the key is a conflict. A later envelope effective_at on an otherwise identical retry keeps the first accepted instant. A new key means a new command. A domain no_change response has no receipt.

Fetch an accepted command receipt with GET /v1/commands/{id}. This reads its outcome without running it again.

Document: immutable evidence or a frozen definition

A document is an immutable artifact the books rely on. It can be a source received from outside, such as an order form or vendor invoice, or a definition, contract or statement produced while recording the business’s activity.

Receiving a source document preserves the original bytes; it does not by itself classify an expense or post money. documents.receive returns a documentId for the registered document and a cid for its content. A CID fingerprints exact bytes; a document id names the registered document in these books. They are different identifiers.

Documents can relate to one another: a contract can be based on source documents, and a correcting statement can supersede another statement. The original stays available. Read documents through /v1/documents and their relations through /v1/documents/{id}/relations.

Ingestion is a separate inspection workflow. It keeps a submitted source and produces a proposal, missing information or a failure. Submission alone does not mean the proposed economics were accepted into the books.

Event: the fact that was recorded

An event is a fact in the business’s permanent history, such as a party being created or contract economics being recorded. It carries its outcome; replaying history does not ask an external service to decide it again.

An event has an id in the business’s history, a content-addressed cid, and a prev link to the preceding event. Corrections append new events; they do not edit or delete the old ones. GET /v1/events reads bounded pages of history, and GET /v1/events/head identifies its latest event.

effective_at says when the fact happened in the world. recorded_at says when it entered the history. A report’s effective-date window can therefore differ from the order in which events arrived. Use the date semantics in that report’s schema, especially when an end date includes a whole UTC day and an end instant excludes the instant itself.

Record: the current lifecycle view

A business record is something you can look up and follow through its lifecycle: a contract, a recording, an opportunity or a message. The API calls these subjects. For example, GET /v1/subjects/contract/{id} returns a contract’s current status and state.

A record’s current view is built from history. It is not permission to overwrite the historical documents behind it. Make changes through the appropriate command, with its expected version or status where required.

Contract: what the parties agreed to

An activity defines a right: service access, hours of work or units of usage, with its terms, calculation and accounting treatment. A template bundles rights for one kind of agreement. A contract makes that agreement with named parties and concrete terms, freezing the definitions it uses.

Creating a draft contract does not mean it was accepted or that anything was billed. Acceptance is a separate lifecycle command with evidence. Recording a right under it describes what actually happened: billing, delivery, usage or recognition, depending on that right’s model.

An occurrence identifies one exercise of a right, such as July’s billing period. A sourceFactId names the observation behind it. Keep real source identities stable so the same fact does not become two recordings. The command’s idempotency key and the source fact’s identity solve related, distinct jobs.

Ledger, account and posting: how the books balance

A ledger is one self-balancing book in one native unit, such as USD, shares or usage units. A business may have several ledgers. Amounts in different units are never simply added together. Use GET /v1/ledgers and returned ledgerId values to inspect what exists.

An account is a numbered line in a ledger’s chart, such as trade receivables, cash or revenue. A posting is one debit or credit to an account. An event’s postings balance within each ledger. A sub-key identifies whose or which balance an account line belongs to, such as the customer on receivables.

A financial account is a bank account, wallet or card the business records. It is distinct from a chart account. Registering an operating bank account does not prove it contains any money. Payment commands record completed money movements; they do not initiate bank transfers.

JSON money is an integer string in minor units: "4900" in a two-decimal USD ledger means USD 49.00. Keep its unit and ledger with it. Do not convert amounts to floating-point numbers to do arithmetic.

Billing, payment and recognition are different facts

The sandbox walkthrough records one monthly USD 49 service invoice billed in advance:

Fact recordedEffect
Draft contractThe proposed agreement exists; no invoice or cash.
AcceptanceThe contract is active; no invoice or cash yet.
July billingTrade receivables "4900"; deferred revenue "4900".
Payment, if separately recordedMoney received; allocate it to the claim it settles.
Recognition, if separately recordedRevenue earned for the evidenced service period.

The walkthrough stops at billing. In a fresh sandbox, its July income statement has revenue "0", expenses "0" and net income "0". The balance sheet has USD 49.00 of receivables and deferred revenue. An unpaid invoice is not cash, and an advance invoice is not automatically earned revenue.

A claim is an amount owed to or by the business. An invoice is a commercial claim billed to a customer; a vendor bill is one billed to the business. Payments stand independently and can be allocated to claims later. A contract does not prescribe how its claims are paid.

Report: a read-only view or calculation

Reads fetch records, documents and history. Reports compute views such as a balance sheet, income statement or aging of outstanding claims. GET /v1/reports lists kinds and inputs; POST /v1/reports runs one. That POST reads a report and does not change the books. Some reports summarize recorded facts; others, such as model_preview, calculate scenarios from supplied assumptions. The report description explains which inputs and facts it uses.

Choose a native currency and an explicit date window when comparing numbers. Follow collection cursors; one page is not the entire business. Empty books show only what has been recorded, not evidence of cash, revenue or runway.

When a number looks wrong, trace it through its ledger postings, the originating recording and contract, and the source evidence. Correct the fact with the appropriate command; keep the original history intact.

Navigate documentation