Using the API
Drafts and confirmations
Integrations create drafts. Sends need confirm true unless the key is auto-send, and destructive or money-moving actions always need confirm true.
Anything that reaches your client or cannot be undone needs a clear yes from a person. That is the rule behind two behaviours of the API: drafts first for everything integrations and AI create, and explicit confirmation for sends and destructive actions. It protects you from a buggy script, a confused AI assistant, or a prompt hidden in a pasted email.
Drafts first
Integrations, MCP clients, the CLI and the AI agent create drafts. A draft invoice has no number yet, is not visible to the client, and can be edited or deleted freely. Nothing leaves your account until something sends it.
- Create an invoice and Create an estimate always create drafts.
- The draft gets its number from the business's gap-free sequence when it is first sent, so abandoned drafts never leave gaps in your numbering.
- A draft can be removed with Delete a draft. Once a document has been sent it can no longer be deleted; it can be voided or credited instead.
Sending needs confirmation
Sends deliver something to a client, so they need confirmation unless the caller is allowed to auto-send.
| Caller | Send without confirm | Send with "confirm": true |
|---|---|---|
API key or MCP token in draft_only mode (default) | Returns the preview and 428 confirmation_required; nothing is sent | Sends |
API key or MCP token in auto_send mode | Sends | Sends |
| A person in the web app | The app shows a confirmation dialog | Sends after the person clicks |
This applies to Send a document and, from the week of 11 January 2027, to Send a reminder.
Preview first
Before you confirm, look at what will happen. Preview a send is read-only and returns what the send would do, without doing it.
curl -X POST "https://api.freeinvoiceautomation.com/v1/documents/0193f2b4-5a6b-7c8d-9e0f-1a2b3c4d5e6f/send-preview" \
-H "Authorization: Bearer $FIA_API_KEY"A good pattern for your own tools: call the preview, show it to a person, and only send "confirm": true once they approve.
Destructive and money-moving actions
Some actions change money or remove access and cannot be simply undone. These are marked destructive (hint D) on their endpoint pages. They need "confirm": true from every caller, including auto_send keys. Without it, the API runs the capability's preview, returns it, and answers 428 confirmation_required.
{
"error": {
"code": "confirmation_required",
"message": "This action needs confirmation. Send the request again with \"confirm\": true.",
"details": {
"preview": { "document_id": "0193f2b4-5a6b-7c8d-9e0f-1a2b3c4d5e6f", "action": "void_document" }
},
"request_id": "req_0193f2a2c0e2"
}
}The preview describes what the action would do for that capability. Read it, then repeat the request with "confirm": true and an Idempotency-Key.
Which actions are destructive
| Area | Action | Notes |
|---|---|---|
| Documents | Void a document | Refused with document_has_payments when payments exist; issue a credit note instead |
| Documents | Create a credit note | Can refund through the rail or leave client credit |
| Documents | Delete a draft | Drafts only |
| Payments | Refund a payment | Goes through the rail when it supports refunds |
| Payments | Delete a payment | Manual records only; soft delete |
| Clients | Delete a client | Soft delete |
| Businesses | Delete a business | Also needs a fresh sign-in |
| Connections | Delete a connection | Removes a payment rail, sender or AI key |
| Team | Deactivate a member, Remove a member, Delete a role | Never the Owner |
| Account | Delete the account | Owner only, fresh sign-in |
| Account | Transfer ownership | Owner only, fresh sign-in |
| Developers | Revoke an API key, Unlink a connector install | Immediate |
| Billing | Remove the billing card | |
| Saved cards (March 2027) | Set auto-charge | Needs the client's consent |
| Accounting sync (May 2027) | Disconnect accounting | |
| Ledger (June to July 2027) | Reverse a journal entry, Unlock a period | Proposed as destructive |
Over MCP, the same tools carry the destructiveHint annotation, so assistants ask you before calling them. void_document and create_credit_note always need confirm: true over MCP, whatever the token's mode. See MCP drafts and confirmations.
Fresh sign-in is separate
A few actions also need a fresh sign-in from a person in the web app: connecting a payment rail, deleting a business, billing changes, creating an auto_send key, turning on auto-send for an automation or a store install, connecting QuickBooks or Xero, adding an AI key, buying a credit pack, adding a billing card and deleting the account. "confirm": true does not replace that. API keys cannot perform these actions (proposed); the API answers fresh_signin_required. See Authentication.
Turning on auto-send
You can let a trusted integration send without confirmation in three places. Each one needs a fresh sign-in and is recorded in the audit log:
- an API key or MCP token created with
mode: auto_send, - an AI agent automation with auto-send turned on,
- a Shopify or WooCommerce install with send automatically turned on.
Auto-send never covers destructive actions. Those still need "confirm": true.
Store events that mirror what already happened
Shopify and WooCommerce are a special case. When an order is cancelled or refunded in the store, the money has already moved or the order is already gone, so mirroring it is recording a fact, not making a new decision. The connector therefore calls Void a document or Create a credit note with "confirm": true automatically. Each one is audited with actor type connector and shows up in the document's activity list. Sends to the store's customer still stay drafts unless "send automatically" is on. See Shopify and WordPress and WooCommerce.
Payments are never marked paid by a redirect
A related rule: a document becomes paid only from a verified payment event (a signed Stripe webhook, a verified store channel), a reconciliation run, or a person recording the payment, which is audited. A client returning from a checkout page does not mark anything paid. Record a payment is the audited human confirmation.