Skip to documentation
amolfiDocs
Open workspace
ContentsAPI overview

Your workspace.
From first steps to API.

Learn how Amolfi works, build on its capabilities, and put your business in motion.

01

Get startedMake it yours.

02

Build with AmolfiMeet the API.

03

Trust & policiesKnow the details.

01

Get started

What is Amolfi?

Amolfi is one workspace for running a whole operation — CRM, projects and delivery, finance, knowledge, and marketing — in one place, over one shared model of your business.

One connected model, not a dozen tools

A client, a deal, a project, an invoice, and a document are the same connected records, not copies kept in rough sync across separate apps. Because everything is connected, the AI built into the product can reason across your whole business instead of one silo at a time.

  • CRM, prospecting and leads
  • Projects and delivery
  • Finance
  • Files and company knowledge
  • Marketing — social and email
  • Contracts and meetings

Who Amolfi is for

Amolfi is built for small and growing service businesses — agencies, studios, consultancies, and trades — that are tired of stitching together a dozen tools and want to run the entire operation, from first lead to paid invoice, in one place with AI that can actually help.

Create your workspace

Start by telling Amolfi about your business. The setup questions come before you create an account, so your workspace begins with context about the work you do.

From setup to workspace

After the setup questions, create your account and continue the workspace setup. Plan selection comes after onboarding.

  1. Tell Amolfi about your business.
  2. Create your account with Google or email.
  3. Continue the guided setup for your workspace.

Where you land

Sign in to the app at amolfi.ai. In your workspace, use Chat to talk to Amo and open the other workspace surfaces to find your records, work, and settings.

Map your business

Amolfi works best when it’s grounded on your real business. Setup means mapping your org — your clients, your services, and your team — so Amo can answer about your business instead of answering generically.

Why mapping matters

An assistant that only knows general facts about your industry gives generic answers. An assistant that knows your actual clients, your actual services, and your actual team gives answers grounded in your business.

  • Your clients and the relationships between them
  • The services you offer
  • Your team and how work is organized

Built for this stage

The Starter plan is built for exactly this stage — setting Amolfi up on your business, before you’re running day-to-day work through it.

Plans & usage

Amolfi has six plans: Starter, Pro, Max, Ultra, Business and Enterprise. Start with how many people need to work in the workspace and how much work you want to delegate.

Choosing a plan

Starter, Pro, Max and Ultra are single-member workspaces. Starter is where you set Amolfi up on your business and run your first real work through it, and it comes with a 14-day trial that takes a card. Pro is one person running a real business on Amolfi, with 3× Starter’s usage. Max is one person with the biggest engine: 8× Starter’s usage, Moonshot and the bigger machine, with Social linking included. Ultra is the most Amolfi sells one person: 30× Starter’s usage and Ultrawork. Business is priced by the person, two people minimum: each person holds a Team seat, with Pro’s usage and computer, or a Team+ seat, with Max’s, and you can mix the two. Every plan runs every model; the plans differ in how much work they carry and how far it can go. Enterprise is for a contracted envelope, custom security and terms, procurement, or invoicing. If you’re between two plans, start lower — moving up keeps everything you’ve already set up. An owner or admin can open Settings, choose Billing & Usage, and change plan. Enterprise and changes between monthly and yearly billing go through the team.

What each plan includes

  • Starter — the whole Amolfi workspace: agentic chat on every model, effort through High, 30 minutes a day on its own computer for each Amo, one machine awake at once, pictures and clips up to 5 seconds, bank linking, one member. Social linking is not part of Starter.
  • Pro — everything in Starter at 3× the usage, 2 hours a day on its own computer for each Amo, two machines awake at once, clips up to 10 seconds, and API keys for outside agents, the CLI and MCP clients. Social linking is available as a $49-a-month add-on. One member.
  • Max — everything in Pro at 8× Starter’s usage, plus Moonshot, the bigger machine, 4 hours a day on its own computer for each Amo, three machines awake at once, the longest clips the provider makes, and Social linking included. One member.
  • Ultra — everything in Max at 30× Starter’s usage, plus Ultrawork and 8 hours a day on its own computer for each Amo, five machines awake at once. One member.
  • Business — priced by the person, two people minimum, on any mix of two seats. Team ($100 a month) gives that person everything in Pro: 3× Starter’s usage and 2 hours a day on its own computer for each Amo, two machines for each person awake at once. Team+ ($250 a month) gives them everything in Max, Moonshot included: 8× Starter’s usage and 4 hours a day on its own computer for each Amo, three machines for each person awake at once. Every seat carries Social linking, team roles and permissions, approvals and review flows, and a shared company memory and knowledge base.
  • Enterprise — every feature, Ultrawork included, plus expert-designed agents, advanced security and admin controls, white-glove onboarding, agent deployment planning, procurement, invoicing and net terms, custom terms, and a dedicated support line. Every contract carries an agreed usage envelope.

Members and usage

Only Business charges per member: a Team seat is $100 a month and a Team+ seat is $250, and each seat brings that person the weekly usage of the plan it mirrors. Each person’s usage is their own by default; an owner can choose to share it across the team. Starter, Pro, Max and Ultra are single-member workspaces — one active membership, of any role. Enterprise is written into the contract.

02

Amo & chat

Talking to Amo

Amo is the AI inside Amolfi. Open Chat in your workspace to start or continue a conversation.

Ask in your own words

You don’t need to learn a command syntax or memorize where a feature lives. Ask Amo in your own words, and it works from the context of your workspace to answer or act.

Amo works from the workspace context and records it is permitted to read. That lets it reason across CRM, projects, finance, knowledge, and marketing in the same conversation.

Delegating work

Amo doesn’t just answer questions — it can own real work: research a lead, draft a campaign, update a record, or summarize a meeting.

Choose a working style

Ask means Amo does the work and pauses only when your judgment would materially improve the result. Auto is the default: Amo assumes you may walk away, makes reasonable judgment calls, keeps durable work moving, and returns with a useful result.

Working style never grants approval. Money, outbound sends, signing, publishing, destructive actions, and other consequential work still stop at the same permission, risk, cost, and named-owner controls. A request for missing input is separate from an approval card; replying can resume the run, but it cannot approve an action.

Agents re-enter the same action handlers a person would click in the UI, running as the person who asked. That means an agent can never do something the person delegating couldn’t do themselves — same permissions, same scope.

Every run leaves a receipt

Every run leaves an attributable record: who asked, what ran, and what it touched. Nothing runs anonymously.

Approvals & governance

Anything touching money or leaving your workspace waits for a named owner to approve it. An agent can prepare the action, but it cannot approve its own work.

The rule that never bends

Money and anything outbound — a client email, a public post, or a contract sent for signature — always becomes an approval card that a workspace owner has to approve before it runs. The agent cannot self-approve, no matter how routine the action looks.

Bounded by design

  • Each agent is bounded — a hard risk ceiling and a kill switch, so one agent can never borrow another’s authority.
  • Agents run as the person who asked, with that person’s own permissions — never more.
  • Sensitive actions append to an audit log as they happen, so there’s a written record of what happened and who approved it.

The result is an assistant that moves fast on the low-risk parts of the work and stops, visibly, at the parts that need a human decision.

Attachments & files

You can attach supported documents and images directly in a conversation, and Amo reads them as part of the work you delegate — a short PDF to review, a screenshot to explain, or a CSV export to summarize.

Where files live

A file you attach stays with the conversation it was shared in, so it’s still available to download when you return. Attachments are not added to Cloud automatically.

If a document should be somewhere the whole team works from it, add it in Cloud — chat attachments stay with the thread.

03

Workspace & members

Members & roles

Amolfi has six workspace roles, from Owner to Guest. Each person sees exactly the work they need — no more.

The six roles

  • Owner — the workspace’s final authority: roles, settings, and everything below.
  • Admin — manages setup, members, and module configuration.
  • Member — runs the day-to-day work across the modules they’re given.
  • Viewer — read-only visibility, sees the work without touching it.
  • Hire — scoped onboarding access while a new person ramps up.
  • Guest — sees only the items shared with them, not the whole module.

Finer-grained control

On top of the six roles, access can be refined per module, and a guest can be scoped down to a single item rather than an entire module.

Invites & member limits

Starter, Pro, Max and Ultra are single-member workspaces — one active membership, of any role. Business is priced by the person, two people minimum: each member holds a Team or a Team+ seat. Enterprise is written into the contract.

What a member costs, and what they bring

On Business, a Team seat is $100 a month and a Team+ seat is $250. Each seat brings that person the usage and computer of the plan it mirrors, so what the workspace gets grows with the team rather than being divided by it.

The meter itself still counts work rather than headcount: what you spend inside the envelope scales with how much work Amolfi does for you, not with how many people are looking at it.

04

The platform

CRM

A standalone CRM sees a pipeline: the deal, the stage, the next follow-up — and almost nothing about what happens after someone says yes. Amolfi’s CRM is rebuilt around the whole customer, not just the sale.

One record, not one more silo

Clients, contacts, deals, notes, files, and activity history live as a single customer record. The same record the pipeline runs on is the record the project and the invoice run on, because in Amolfi they’re the same connected records.

  • Clients, contacts, deals, notes, files, and history in one record.
  • The CRM sees the invoice and the project because they’re the same records.
  • Update the customer once — the pipeline, the project, and the invoice all see it.

The pipeline is where a customer starts. It isn’t the only thing your CRM remembers about them.

Projects & delivery

A request becomes tracked work the moment it lands: intake, tasks, deliverables, approvals, and timelines all live on the same board.

One board, start to finish

Nothing has to be copied into a second tool to become real, and nothing disappears in a handoff between tools — because there is no handoff between tools.

  • Intake becomes tracked work automatically — no re-entry.
  • Tasks, deliverables, approvals, and timelines share one surface.
  • Delivery sits beside the client record and the invoice it belongs to.

Delivery in context

Delivery lives in the same workspace as the client and the invoice, so the work carries its own context — who it’s for, and what it’s worth — instead of floating in a generic project tool that only knows about tasks.

Finance

Amolfi’s books of record are cash basis by default — money is recorded when it actually moves, the way most owners already keep score in their head.

Cash basis by default

Cash-basis books match the way a small team watches cash: income and expenses are recorded when money moves. You do not need to maintain accrual entries or a general ledger inside Amolfi.

  • Cash basis by default — recorded when money moves, not when it’s promised.
  • One set of books, with no accrual bookkeeping to maintain.
  • Bank data via Plaid, so the books match the account.

Bank connections come in through Plaid, so the money that actually landed is grounded in the account it landed in — not a number someone re-typed from a statement.

Cloud

Cloud is where every document, contract, receipt, and asset the business keeps lives — one governed home for the whole workspace.

The Company Brain

The Company Brain renders your whole business as one explorable graph — the same graph your team browses and your AI agents reason over.

Grounded authoring, not generic drafts

Amolfi’s doc suite is one editor for docs, slides, and sheets. Its AI drafts from the records already in your workspace — the real client, the real deal, the real invoice — instead of a generic model reaching for something that fits.

When it states a number, it pulls it from the record it came from and cites the source so you can click back to it. When it can’t find the record, it says so instead of filling the gap.

A person still decides

The AI drafts; a person still edits and decides. Grounding gives you sources to check, and you should review the numbers before using the result.

Social media

Plan and draft posts for your connected social accounts in one place. Write an idea once, and AI drafts per-platform variants from it.

Approval before anything posts

Publishing is approval-gated — a draft waits for a person to approve it. Nothing posts on its own.

Planning the week

A planner view lays the week out, so you can see what’s drafted and what’s scheduled across your accounts at a glance.

Contracts & signing

Prepare a contract from a template, send it for signature, and track its status — all in the same workspace as the client it belongs to.

From template to signed

  1. Prepare the contract from a template.
  2. Send it for signature.
  3. Track its status alongside the client record.

Signing

Signers receive a branded email and sign electronically.

05

Usage & billing

How usage works

Two words that never mix. Usage is what the plan gives you: an amount each week, shown as a percentage with the date it resets. Crowns are what you buy when you want more than the plan gives, at 400 to the dollar.

The week

A usage week belongs to your workspace. It starts the first time the workspace runs work after the last week ended and lasts seven days, so it follows how you work rather than a calendar or your billing date. Usage does not carry over: a week you did not use is not banked.

On a team, every member has their own weekly amount by default, inside the workspace’s week, with the workspace total above it. An owner or admin can switch to sharing the workspace’s usage across the team instead.

What counts as usage

Usage is measured by the work Amolfi actually does for you — AI, meetings, research, communications, document processing, automations, and agent tasks — so you never have to reason about raw model tokens.

Tracking your usage

Your workspace shows how much of the week’s usage is spent, when it resets, and your Crowns balance beside it with the date the soonest-expiring Crowns run out. The plan’s usage is spent first; Crowns are spent after it, if you have any and the switch is on.

Storage and downloads

Storage and the downloads included each month are shown beside the usage bar. Those two allocations are still monthly — it is plan usage that is weekly. Past either allocation you pay from your Crowns — 12 Crowns per GB a month for storage, 45 Crowns per GB for downloads — and Amolfi tells you what comes next before you get there rather than stopping you at it.

Running out of usage

Your workspace stays active. What happens next depends on one switch: Use my Crowns when plan usage runs out. It is on whenever your Crowns balance is positive, so work carries on and draws from the balance. Turn it off and the plan is a hard stop until the week resets.

If the balance is empty

Amolfi offers you Crowns before anything refuses. New metered work pauses before provider spend rather than running first and billing afterward.

What can pause metered work today

Amolfi may pace an unusually heavy burst so that one runaway job cannot spend a shared workspace’s week in an afternoon. Pacing bounds how fast usage is spent, not how much the plan includes.

Your records, completed results, approvals, and billing remain available if a protective limit pauses new metered work.

If we give you a usage reset

Amolfi sometimes gives a workspace a promotional usage reset — after an incident, or as a goodwill gesture. Using one starts a new usage week straight away, so your usage reads as unused and the next reset moves seven days out. An owner or admin uses it from Settings. A reset expires if it is not used, has no cash value, and changes nothing except your usage week.

If your plan lapses

Crowns you have bought are held rather than burned, and their 12-month clock stops until you come back. It starts again on your next successful charge.

Annual billing

Annual billing changes what you pay and when, not how Amolfi attributes usage.

The same usage model

Usage is still weekly, and it still resets on your workspace’s own week rather than on your billing date. What annual changes is the price and the invoice.

The annual price

Paying annually shows a discounted monthly rate compared to paying month to month, billed as one annual charge.

Upgrading your plan

If you’re between two plans, start lower. Moving up keeps everything you’ve already set up.

Change plan in Settings

  1. Open Settings.
  2. Choose Billing & Usage.
  3. Under Change plan, choose Starter, Pro, Max, Ultra or Business.

Upgrades take effect immediately and Stripe invoices the prorated difference. Your records, configuration, and history stay with the workspace.

Self-serve plan changes keep your current billing interval. Moving up applies immediately, re-anchors your billing cycle to that moment, and credits the proration — the confirm screen says so before you agree to it. Moving to a lower plan uses the same Change plan control and takes effect at the end of your current billing period, with no mid-cycle refund and nothing you have set up removed. Changing between monthly and yearly billing, or moving into or out of Enterprise, is handled with the team.

06

Security & data

How Amolfi protects your data

Amolfi processes workspace data to provide AI assistance, maintain safety controls, create work receipts, debug errors, and improve product quality. It does not sell personal information or share it for cross-context behavioral advertising. The Privacy Policy describes these uses and your rights.

Grounded, not generic

The AI is grounded on your own records — that’s what makes an answer about your business instead of a generic one. Your workspace is isolated from every other organization at the database layer, not just in the interface.

Agents propose, owners approve

Agents propose rather than act: anything that moves money or leaves your workspace waits for a named owner to approve it, and sensitive server actions append to an audit log as they happen.

Service credentials are kept server-side. Access to bank items, billing, audit logs, and signing requests goes through server endpoints that enforce their own checks.

Isolation

Your workspace is a sealed room. CRM, projects, finance, legal, and marketing run natively inside one boundary — not stitched across six vendors’ clouds. Every read and write is gated by membership at the database layer; deactivate a member and their access ends with them.

Governed AI

AI with a gate, not a free hand. Agents draft from the records they’re permitted to read; risk tiers and review gates sit before anything a client could see; approved actions leave receipts — sensitive fields stripped first.

Audit log

If it mattered, it’s in the log. Sensitive server actions append to an audit log as they happen — history is added to, not edited — with redaction at write time.

Roles and access

Six roles, drawn precisely. From owner to guest, each person sees exactly the work they need — with per-module overrides and item-level guest scoping on top.

Server-only secrets

Service credentials stay on the server. Workspace API keys are shown once when you create them; store them securely. Requests for sensitive records go through server endpoints that enforce their own checks.

One link, one job. Client intake forms, approvals, document signing, booking, creator delivery, and portal views — each link does the one thing it was made for, nothing else.

Transport and files

Hosting sends HSTS, X-Frame-Options, X-Content-Type-Options, Referrer-Policy, Permissions-Policy, and a report-only Content Security Policy on live responses. File download endpoints re-check workspace or conversation access and return short-lived signed URLs.

Integrations

Connections that prove themselves. Inbound webhooks verify provider signatures or HMAC tokens before anything is processed; outbound OAuth uses single-use, HMAC-bound state. Bank connections run through Plaid Link — credentials are entered with Plaid, never in Amolfi.

Reporting a vulnerability

Found something? Email security@amolfi.com directly.

Where to read more

The commitments above are contractual in the privacy policy and the terms:

API & CLI

Live schema

API overview

Amolfi has a public API at https://api.amolfi.com. It is a door into your workspace — the same records, the same permissions, and the same approval gate you see in the app — not a model API you send prompts to.

Not a model API

Nothing on this surface is a new data path. Every operation resolves to a tool the product already runs, which already carries a permission, a risk class, and a receipt. A machine caller reaches your business the same way a person clicking in the app does, and it is held to the same rules.

Two shapes

Call a governed tool. Your own agent or script decides what to do and calls one capability — list clients, read invoices, draft a post. You get a result and a receipt.

POST /v1/tools/{tool_name}
Authorization: Bearer amolfi_sk_…

{ "…": "the tool's own input" }

Hand over a goal. You describe an outcome and Amolfi decides how to do it — Amo routes the work to the right specialists, runs it against your real workspace, and files an approval card the moment something needs a human. Your side does no reasoning about *how*.

POST /v1/runs
{
  "goal": "draft the october email from what actually shipped",
  "working_style": "autonomous",
  "effort": "normal"
}

Both shapes use one contract, one permission model, and one approval gate.

Look before you authenticate

Three routes need no credentials at all, so you can read the contract before you mint anything. These are runnable right now:

curl https://api.amolfi.com/v1/health
curl https://api.amolfi.com/v1/scopes
curl https://api.amolfi.com/v1/openapi.json
  • /v1/health — liveness.
  • /v1/scopes — every scope, the tools behind it, and which roles may be granted it.
  • /v1/openapi.json — the whole contract as OpenAPI 3.1, generated from the same catalog the API routes from, so the spec cannot drift from the surface.

What a machine caller cannot do

It cannot send, spend, sign, or publish. Those actions return an approval card instead of a result, and a workspace owner approves them in the app. This is not a setting — the strongest scope available for an outward action is propose, and no send, pay, or post scope exists to grant.

Requests and errors

Requests and responses are JSON. Every response carries x-amolfi-request-id — quote it if you ever need to ask about one — and x-amolfi-api-version. Errors share one envelope, so you can branch on code rather than on prose.

{ "error": { "code": "SCOPE_REQUIRED", "message": "…" } }
  • 401 — the token is missing, invalid, expired, or revoked. Every failure looks identical, so a probe learns nothing.
  • 403 — SCOPE_REQUIRED when the token lacks the scope, FORBIDDEN when the permission check refuses. Nothing ran.
  • 404 — NOT_FOUND, which also covers anything outside your workspace. That is deliberate: a 403 would confirm the thing exists.
  • 409 — an Idempotency-Key conflict (see below).

Retrying safely

Send an Idempotency-Key header on anything that writes or proposes. An identical replay returns the stored response and does no new work; the same key with a different body is refused with IDEMPOTENCY_CONFLICT rather than quietly doing something else. Keys are remembered for 24 hours.

curl https://api.amolfi.com/v1/tools/finance_list_invoices \
  -H "Authorization: Bearer $AMOLFI_API_KEY" \
  -H "Content-Type: application/json" \
  --data '{"status":"open","limit":3}'
200 OK · example data.invoices
[
  {
    "id": "11111111-1111-4111-8111-111111111111",
    "invoice_number": "INV-1042",
    "customer_name": "Acme Studio",
    "currency": "USD",
    "status": "sent",
    "total_cents": 420000,
    "outstanding_cents": 420000
  }
]

Illustrative invoice fields. The full result includes status, data.receipt and meta; check meta.truncated.

Authentication

There are two ways to authenticate, and which one you want depends on whether a human is present. Automation carries a workspace token. A person at a terminal signs in through the browser.

Workspace tokens

A workspace token is minted in the app — Settings → API keys — and looks like amolfi_sk_…. It is shown once, at mint time. Amolfi stores only its hash, so nobody, including Amolfi, can read it back to you later. Lose it and you mint a new one.

The token names its workspace inside itself, so there is no workspace header to set and nothing in a request can widen its reach. One token, one workspace.

Authorization: Bearer amolfi_sk_…

A token is a delegation, not a new identity

Every request is checked against the live permissions of the member who minted the token, re-resolved on each call. Narrow that person’s access and the token narrows with it on the very next request. Revoke the token, or deactivate the member, and it stops working immediately.

Scopes are the second gate. A token carries scopes from the public catalog, and the effective authority of any call is the intersection of the token’s scopes, the minter’s live permissions, and the tool’s own permission requirement. Read /v1/scopes to see the whole table before you mint anything.

Signing in from a terminal

For a person, pasting a long-lived secret into a shell is the wrong shape. amolfi login runs the OAuth 2.1 Device Authorization Grant (RFC 8628) instead: the terminal opens the server-issued authorization page in your default browser, where the existing Amolfi login and 2FA policy apply, and you pick the workspace there rather than in the terminal. An existing browser session is reused. Headless, manual, and opener-failure paths print the URL and short code as a fallback.

POST /v1/auth/device/code    → device_code, user_code, verification_uri_complete, interval, expires_in

  # open the returned verification_uri_complete, confirm the code, and pick a workspace

POST /v1/auth/device/token   → 428 authorization_pending  (keep polling)
                             → 429 slow_down             (poll slower)
                             → 200 access_token, refresh_token, org_id, scopes

Both device routes are form-encoded (application/x-www-form-urlencoded), as RFC 8628 requires — a JSON body is refused. Poll no faster than the interval the server returns, and back off when it says to.

Sign-in returns a short-lived access credential — under an hour — plus a rotating refresh credential. Refreshing consumes the old one; reusing a spent refresh credential revokes the whole grant, because reuse is what a stolen credential looks like. The grant is also bound to the permissions you held when you approved it: change them and the grant closes rather than quietly widening.

Which one to use

  • Workspace token — n8n, CI, cron, anything unattended. Export it as AMOLFI_TOKEN.
  • Device sign-in — a person working in a terminal. Run amolfi login.
  • Neither — /v1/health, /v1/scopes, and /v1/openapi.json need no credential at all.
curl https://api.amolfi.com/v1/tools/finance_list_invoices \
  -H "Authorization: Bearer $AMOLFI_API_KEY" \
  -H "Content-Type: application/json" \
  --data '{"status":"open","limit":3}'
Response headers
Content-Type: application/json
X-Amolfi-Request-Id: <request-id>
X-Amolfi-Api-Version: 2026-08-12

Set AMOLFI_API_KEY in your server environment. This example requires finance.invoices.read.

API schema

The public OpenAPI document describes available tools, their inputs, responses and authentication requirements. Use it to build an integration against the current contract.

/v1/openapi.jsonGET · public
The machine-readable OpenAPI 3.1 document.
/v1/scopesGET · public
Discover scopes, associated tools, actions and roles.
/v1/healthGET · public
Check that the API is reachable.

These discovery endpoints do not require a key. Authenticated workspace requests belong on your server.

Open the live schema
curl https://api.amolfi.com/v1/openapi.json
200 OK · schema excerpt
{
  "openapi": "3.1.0",
  "paths": {
    "/v1/tools/finance_list_invoices": {
      "post": { "operationId": "finance_list_invoices" }
    }
  }
}

Excerpt only. The live schema includes request bodies, responses and security requirements.

Read workspace data

Bring workspace records into your internal tools. Call a named tool with its JSON input and receive a structured result.

POST/v1/tools/finance_list_invoices

This example fetches up to three open invoices. It requires finance.invoices.read.

statusstring · optional
Filter by invoice status. This example uses open.
limitinteger · optional
Maximum number of invoices to return. This example uses 3.

Read the result

Invoice records appear in data.invoices. Amounts such as total_cents use minor currency units. The result also includes a receipt and envelope metadata.

Check meta.truncated before treating a result as complete.

curl https://api.amolfi.com/v1/tools/finance_list_invoices \
  -H "Authorization: Bearer $AMOLFI_API_KEY" \
  -H "Content-Type: application/json" \
  --data '{"status":"open","limit":3}'
200 OK · example data.invoices
[
  {
    "id": "11111111-1111-4111-8111-111111111111",
    "invoice_number": "INV-1042",
    "customer_name": "Acme Studio",
    "currency": "USD",
    "status": "sent",
    "total_cents": 420000,
    "outstanding_cents": 420000
  }
]

Illustrative invoice fields. The full result includes status, data.receipt and meta; check meta.truncated.

Runs

A run is the second shape: you hand Amolfi a goal instead of a tool call. Amo triages it, delegates to the specialists that own the work, and follows it against your real workspace — the same work you would watch happen in chat.

Start one

Starting a run returns 202, never 200. A run is asynchronous by nature, and a run id must never read as finished work.

POST /v1/runs
{
  "goal": "draft the october email from what actually shipped",
  "working_style": "autonomous",
  "effort": "normal"
}

202 { "status": "queued", "run_id": "…", "working_style": "autonomous", "effort": "normal" }

Choose how involved to be

  • collaborative — Ask. Amo does the work and pauses only when your judgment would materially improve the result.
  • autonomous — Auto. The default. Amo assumes you may be away, makes reasonable judgment calls, and continues as durable background work.

Working style changes collaboration, not authority. It never changes a tool’s permission, risk class, cost ceiling, or approval requirement. Omit it and the server uses autonomous; unknown write values are refused rather than silently mapped.

Choose the reasoning effort

  • low — Fast. Speed first.
  • normal — Normal. The default for everyday work.
  • high — High. The kernel routes the run through the heavy reasoning model.
  • ultrawork — Ultrawork. The kernel uses its separately configurable Ultrawork route.

Effort is durable run state, not terminal decoration. Start, list, status, and receipts carry it, and each execution iteration uses its model route. Effort never changes permission or approval authority.

Find durable work

GET /v1/runs   → up to 25 recent goal-directed runs, current work first

Run history lives on the server, not in one terminal process. The CLI stores only one non-secret selected-run pointer per API origin and workspace so another terminal can use amolfi runs status or amolfi runs watch without inventing local history.

Follow it

GET  /v1/runs/{run_id}           → status, style, effort, specialists, activity, input or approval
POST /v1/runs/{run_id}/guidance  → steer it, or answer a needs_input checkpoint
POST /v1/runs/{run_id}/cancel    → stop it

Poll the run rather than holding a connection open. Each snapshot carries the run’s status, the specialists working on it, and the recent activity lines.

The status vocabulary

A run reports one of seven statuses. This is a deliberately narrow public vocabulary — the internal lifecycle is richer, and it stays internal so it can change without breaking you.

  • queued — accepted, not started.
  • working — in progress.
  • needs_input — parked on one work question. Send guidance to answer it and wake the same run.
  • pending_approval — stopped, waiting on a person. Not an error.
  • completed · failed · cancelled — terminal.

Activity lines are also a projection, not raw internals: they read as amo:…, specialist:…, tool:…, approval:…, or run:…. A tool line can carry the hostname it called. Render that as plain text and never as a link — it is influenced by whatever the tool was pointed at.

When a run needs an owner

needs_input and pending_approval are intentionally different. Guidance may answer a work question. It may never settle an approval.

A run that reaches something outward — sending, spending, signing, publishing — does not execute it and does not fail. It files an approval card and waits. The run surfaces as pending_approval with the decision’s id, and a workspace owner approves or declines in the app.

Machines propose. Owners approve. A run is a goal, not an authorisation.

There is deliberately no approve endpoint. Guidance is guidance — it maps to steering a run that is already yours to steer — and adding an approve verb would be the bypass this whole design exists to prevent, wearing a different noun. The scope vocabulary makes it unrepresentable: propose is the ceiling.

What bounds a run

A run’s reach is bounded by the token’s scopes, not by the goal’s ambition. A goal that needs a capability the token lacks stops with a 403 rather than returning a partial result and calling it done. Running a goal needs runs.runs.write; polling one needs runs.runs.read.

curl https://api.amolfi.com/v1/runs \
  -H "Authorization: Bearer $AMOLFI_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $REQUEST_ID" \
  --data '{"goal":"Draft the October email from what shipped","working_style":"autonomous","effort":"normal"}'
202 Accepted · documented response
{
  "status": "queued",
  "run_id": "…",
  "working_style": "autonomous",
  "effort": "normal"
}

Set REQUEST_ID to a unique value for a new run. Reuse it only when retrying the same request. Poll the returned run ID for progress.

Files API

The Files API lets a workspace token read and write the same Cloud the app shows. A workspace’s documents, sheets, decks, and uploads are Artifacts: one record with a type, a revision history, and provenance you can trace. There is no second machine content service.

Scopes

files.artifacts.read     list, read, search, and trace Artifacts and their revisions
files.artifacts.write    create and edit Artifacts, move, archive, restore, refresh, export
files.records.read       read workspace records and the governed Business Brief
files.records.write      record an inert Business Brief edit proposal

Read and edit a document

POST /v1/tools/artifact_search   { "query": "pricing model" }
POST /v1/tools/artifact_get      { "artifact_id": "…" }
POST /v1/tools/artifact_apply_operation
POST /v1/tools/artifact_export   { "artifact_id": "…", "format": "pdf" }

An edit is an operation against a revision, not a file overwrite, so every change keeps its history and its author. artifact_export renders a format — a PDF of a document, a workbook of a sheet — without leaving the record it came from.

Contracts and the security boundary

The Cloud includes user-uploaded contracts. A category label is editable, so using contracts as an access-control boundary would not protect anything. Separately managed signed-provider documents remain excluded because they live behind signing-specific tables and actions.

Uploads and scanning

Anything a person uploads still goes through the same presign, storage, finalize, and malware-scan path the app uses. Only an explicit clean verdict makes content available. Subscribe to file.available and file.held if your system should be told instead of polling.

curl https://api.amolfi.com/v1/tools/artifact_search \
  -H "Authorization: Bearer $AMOLFI_API_KEY" \
  -H "Content-Type: application/json" \
  --data '{"query":"pricing model"}'

Requires files.artifacts.read. Read the live OpenAPI schema for the current response contract.

Agent sessions

A session is a durable conversation in your workspace. The same sessions you see in the app are readable and startable by a workspace token, so an outside agent works in the conversation rather than beside it.

Scopes

sessions.sessions.read    list sessions, read one, page its events
sessions.sessions.write   start a turn, rename, pin, archive, fork

A token acts for the member who minted it. A session your token starts is owned by that person, appears in their rail in the app, and is visible to owners and admins exactly like one they started themselves. A token is not a new member and never becomes one.

Start a turn and follow it

POST /v1/tools/agent_session_turn_start   { "message": "close the books for July" }
  -> { "session_id": "…", "run_id": "…", "seq": "2" }

POST /v1/tools/agent_session_events_list  { "session_id": "…", "after_seq": "2" }

Events arrive in ascending sequence with a next_after_seq cursor. Poll from the last sequence you stored. A turn started this way is a cloud turn: it keeps running after your process exits, and anything that sends, spends, signs, or publishes still stops at an approval card.

What a session read withholds

Session events are projected field by field before they leave the workspace, so a read gives you the conversation without becoming a side door into everything the conversation touched.

  • Assistant and user text, tool names, run status, and route arrive in full.
  • A tool result arrives only when its result policy is durable_summary. A private or opaque result arrives as coordinates with content_withheld, the same content the API refuses to return if you call that tool directly.
  • Reasoning summaries and model protocol state do not cross. They arrive as coordinates with payload_withheld.

An event kind that does not have a published projection yet arrives as coordinates rather than as its raw payload. Absence in a payload always means withheld, never empty.

What has no machine verb

Approvals settle in the app. There is no endpoint that approves a card, and no scope that could be granted to do it.

Local turns are also first-party. A local turn runs a model on your own machine and reports its progress from that client, so a workspace token cannot start one or append to one. Ask for a cloud turn and the workspace runs it for you.

Use the CLI

amolfi sessions                       # the rail, pinned first
amolfi sessions get <session_id>
amolfi sessions events <session_id> --after 12
amolfi sessions start "close the books for July"
amolfi sessions start "and now August" --session <session_id>
amolfi sessions rename <session_id> "July close"
amolfi sessions pin <session_id>
amolfi sessions fork <session_id> 42 --title "What if we delay"

Forking copies a session up to a sequence you choose. Both sessions continue independently from there, which is how you try a second approach without losing the first.

Continue a conversation

The message input is required for a new task or follow-up. Include the optional session_id to continue an existing conversation; omit it to start a new session.

curl https://api.amolfi.com/v1/tools/agent_session_turn_start \
  -H "Authorization: Bearer $AMOLFI_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $REQUEST_ID" \
  --data '{"message":"Summarize my open invoices."}'
200 OK · example data excerpt
{
  "session_id": "11111111-1111-4111-8111-111111111111",
  "run_id": "22222222-2222-4222-8222-222222222222",
  "seq": "1",
  "route": "cloud",
  "replayed": false
}

Set REQUEST_ID to a unique value for each new request. Reuse it only when retrying that same request.

Webhooks

Register an endpoint in Settings → Webhooks and Amolfi POSTs you a signed JSON body when the business moves. Thirty-one events exist, in twelve families, and every one of them fires from real code — registration rejects any name that does not.

The catalog

deal · contact · client · project    created / updated
invoice                             created / paid
contract                            sent / signed / declined / expired
run                                 waiting_approval / completed / failed / cancelled
booking                             created / updated / cancelled
member                              invited / joined / removed
domain                              verified
apikey                              created / revoked
file                                available / held / updated / archived

Some absences are deliberate, so you do not sit waiting for them. There is no invoice.overdue: overdue is derived at read time from an invoice’s due date and status, so there is no moment to fire on — compute it from the payloads you already get. Imports and backfills never fire events, so nobody floods your endpoint by loading history. And invoice.paid fires only on the terminal transition to fully paid, never on a partial payment.

The envelope

{ "event": "invoice.paid", "timestamp": "<ISO-8601>", "data": { "id": "…" } }

CRM-family payloads carry the entity’s fields. Every other family is an explicit allow-list projection — thin identity and state, chosen field by field, so internals never leave the workspace by accident.

  • invoice — numbers, status, currency, amounts, client, dates. No notes, no metadata.
  • contract — identity and state only. No signer names or emails; fetch detail through the API.
  • run — id, status, title, summary, and the decision id when one is waiting.
  • booking — identity and the time window. No attendees, description, or location.
  • member — ids, status, and role. No email address, in any form — not plaintext, not hashed. Resolve identity with an authenticated roster read, where your own permissions apply.
  • domain — the domain, its purpose, and when it verified.
  • apikey — the key’s public id and status. Never the key, its hash, or any prefix bytes.
  • file — identity, lifecycle status, content type, byte size, rights state, and scan verdict. Never names, descriptions, tags, content, storage coordinates, or scanner threat names.

Delivery is at-least-once

Retries ride a queue, and every attempt is ledgered with a dedupe check taken *before* the POST, so an acknowledged delivery is not re-sent. Even so, treat your handler as idempotent: dedupe on the X-Amolfi-Delivery header for exact retries, and on (event, data.id) if your handler must act strictly once per business moment.

Verifying the signature — read this part carefully

Every delivery carries three headers: X-Amolfi-Event, X-Amolfi-Delivery, and the signature.

X-Amolfi-Signature: sha256=<hex hmac>

The HMAC key is not your raw `whsec_…` secret. Amolfi never stores that secret — you are shown it once and only its SHA-256 is kept — so the key both sides share is the hex digest of your secret, and that is what you must HMAC with. Every subscriber that skips this step sees valid deliveries as forgeries.

signing_key = sha256_hex(raw_whsec_secret)      // the hex digest STRING
expected    = "sha256=" + hmac_sha256_hex(signing_key, raw_request_body)
valid       = timing_safe_equal(expected, X-Amolfi-Signature)

In Node:

import { createHash, createHmac, timingSafeEqual } from 'node:crypto';

function verify(rawBody, header, whsecSecret) {
  const signingKey = createHash('sha256').update(whsecSecret).digest('hex');
  const expected = `sha256=${createHmac('sha256', signingKey).update(rawBody).digest('hex')}`;
  const a = Buffer.from(expected);
  const b = Buffer.from(header || '');
  return a.length === b.length && timingSafeEqual(a, b);
}

Three rules that go with it: HMAC the raw request bytes, not an object you re-serialized — re-serializing changes them. Always compare in constant time. And reject anything unsigned or mis-signed; a delivery that fails this check is not from Amolfi.

Inspect existing subscriptions with admin_webhooks_list and the workspace.webhooks.read scope.

curl https://api.amolfi.com/v1/tools/admin_webhooks_list \
  -H "Authorization: Bearer $AMOLFI_API_KEY" \
  -H "Content-Type: application/json" \
  --data '{}'
Incoming delivery · illustrative event
{
  "event": "invoice.paid",
  "timestamp": "2026-09-22T12:00:00.000Z",
  "data": {
    "id": "11111111-1111-4111-8111-111111111111",
    "invoice_number": "INV-1042",
    "status": "paid",
    "currency": "USD",
    "total_cents": 420000,
    "paid_cents": 420000
  }
}

The delivery above arrives at your registered endpoint; it is not the response to the subscriptions request.

Errors & retries

Use HTTP status and the JSON error code to decide what to do next. Save X-Amolfi-Request-Id when investigating a failed request.

401unauthorized
Check whether the key is missing, invalid, expired or revoked.
403forbidden
Check the required scope and the member’s workspace permissions.
404not found
The resource is unavailable in this workspace.
409conflict
An idempotency key was reused for a different request.
429throttled
Retry with exponential backoff and jitter.

Retry without repeating a write

Send an Idempotency-Key on write and proposal requests. Reuse the same key and request body when retrying; matching requests replay the stored result for 24 hours.

Handle throttling with backoff. There are no rate-limit remaining or reset headers to rely on.

curl https://api.amolfi.com/v1/tools/finance_list_invoices \
  -H "Authorization: Bearer $AMOLFI_API_KEY" \
  -H "Content-Type: application/json" \
  --data '{"status":"open","limit":3}'
403 · example error
{
  "error": {
    "code": "SCOPE_REQUIRED",
    "message": "Required scope: finance.invoices.read"
  }
}

Illustrative error message. Branch on the error code, and retain the request ID for troubleshooting.

CLI

The Amolfi CLI is the terminal client of the API. It reads your workspace, hands Amo goals, and follows runs. Anything that sends, spends, signs, publishes, or otherwise needs an owner still stops for approval.

npm install -g @amolfi/cli

It needs Node 20 or newer and has no runtime dependencies. It is proprietary software, licensed for use with the Amolfi service.

Sign in

amolfi login             # opens the dedicated browser authorization page
amolfi login --manual    # print the fallback URL and one-time code
amolfi logout            # clear the stored credential

The credential lives in your operating system’s credential store, never in a dotfile. For unattended use — CI, cron, a scheduler — skip sign-in and export a workspace token instead:

export AMOLFI_TOKEN=amolfi_sk_…       # minted in Settings → API keys
export AMOLFI_API_URL=https://…       # optional; defaults to https://api.amolfi.com

The verbs

amolfi health                          # liveness — no credential needed
amolfi scopes                          # the public scope catalog

amolfi team                            # roster and roles — who can approve
amolfi webhooks                        # registered endpoints
amolfi audit 50                        # the workspace audit log

amolfi sessions                        # the session rail, pinned first
amolfi sessions start "close the books for July"
amolfi sessions events <session_id> --after 12
amolfi sessions fork <session_id> 42 --title "What if we delay"

amolfi ask "draft the october email from what actually shipped"   # Auto + Normal
amolfi ask --style collaborative "shape the launch with me"      # Ask
amolfi ask --effort ultrawork "audit the launch and finish it"
amolfi runs                            # recent durable work, current first
amolfi runs start --style collaborative --effort high "<goal>"
amolfi runs select <run_id>            # share the selection across terminals
amolfi runs status                     # inspect the selected run
amolfi runs watch [run_id]             # follow selected or explicit work
amolfi runs guidance <run_id> "shorter, warmer"
amolfi runs cancel [run_id]
amolfi runs clear

Add --json to any read for the raw payload. ask is the everyday verb and starts an Auto run at Normal effort by default. In the interactive shell, Shift+Tab or /style opens Ask and Auto; /effort opens Fast, Normal, High, and Ultrawork. Auto returns the run id and lets Amo continue in the background; Ask follows the run and pauses only when your judgment would materially improve the result. The shell session is only the terminal view; working style and effort remain durable server-side state and can be read from another terminal.

Each read needs its catalog scope: for example, team needs workspace.team.read, while run discovery and status need runs.runs.read. A missing scope returns SCOPE_REQUIRED rather than an empty result that looks like an empty workspace.

What the CLI deliberately cannot do

There is no verb to mint or revoke a key, invite or change a member, or connect a provider — and no approve verb. A pending approval prints the exact approval URL and never opens a browser; you go and read the card yourself. The scope that would let a terminal approve does not exist, which is the design, not a gap.

Exit codes

  • 0 — fine, including a run that is waiting on an owner. Waiting is the designed outcome, not a failure.
  • 1 — an API or network error.
  • 2 — a usage or configuration mistake.
npm install -g @amolfi/cli

amolfi login
amolfi health
amolfi scopes

Node.js 20 or later. Follow the device sign-in instructions shown by amolfi login.

Legal

Loading page…