Skip to content
Bkper Bkper

Extractor Bot

by Bkper

Reads your documents and turns them into draft transactions. Drag invoices, receipts, or bank statements into your book — Extractor Bot extracts dates, amounts, and descriptions with AI, asks Bookbot for the right accounts, and records unposted drafts for you to review.

Extractor Bot learns from your corrections and improves its extraction over time. It never posts transactions: you review and post every draft.

How it works

sequenceDiagram participant Book as Bkper Book participant Extractor as Extractor Bot participant Bookbot as Bookbot Book->>Extractor: File uploaded Extractor->>Extractor: Extract transactions Extractor->>Bookbot: Which accounts? Bookbot-->>Extractor: Suggested accounts and properties Extractor->>Book: Create draft transactions Note over Book: Drafts reviewed and posted Book->>Extractor: Transaction posted Extractor->>Extractor: Learn from corrections

Upload — select the account the document belongs to, such as the bank account of a statement, and drop the file into the book. The account sets which learned instructions apply and which side of the drafts it takes. Agents and scripts upload with bkper file upload <path> -b <bookId> --account "<account>". For bank statements and CSVs, Extractor Bot creates one draft per line item. For invoices and receipts, it creates one draft with the file attached. Statement rows can go to another book or account when an external extraction service says so.

Attach — drop a file onto an existing transaction. Extractor Bot fills in the missing amount, date, and description, adds extracted custom properties, and updates the transaction. Attached files are always read as one invoice or receipt, even multi-page statements.

Type — create a transaction without an attachment. Extractor Bot fills a missing amount from the description, and a date written in the description replaces the date Bkper filled in automatically.

CSV files are always read as statements. PDFs and images are analyzed to decide whether they hold a statement table or a single invoice or receipt.

Each uploaded file is read once. After recording its drafts, Extractor Bot stores an extractor_transactions_summary property on the file and skips files that already have one (or the earlier transactions_summary). When extraction fails, no drafts are created, and the error appears in the book activity as Extractor Bot's response to the event. When a statement sends rows to several books, each book is recorded in turn: if one fails, drafts already created in the other books remain and the file gets no summary, so check those books before replaying the event.

Accounts come from Bookbot

Extractor Bot extracts; Bookbot finds accounts. Before recording drafts, Extractor Bot asks Bookbot for the missing From or To account, based on your posted transactions. When every matching transaction shares a custom property, such as category or project, Bookbot copies it onto the draft. Accounts you selected and properties already on the draft are never replaced. To tune how accounts are found, use Bookbot's settings, such as agent_discovery_examples.

If Bookbot cannot be reached, Extractor Bot still records the drafts, without suggested accounts, and its response in the book activity includes a warning.

Learning from corrections

When you correct an extracted draft and post it, Extractor Bot compares it with the original extraction. If the data changed significantly, it writes improved extraction instructions and keeps them only when re-extracting the document gives better results without regressions.

Instructions are saved on the account or group the document came through: extractor_prompt_transaction for invoices and receipts, extractor_prompt_transactions for statements. They are plain text that you can read and edit.

  • Invoices and receipts are learned from right after posting.
  • Statements flag their account or group; each book audit (BOOK_AUDITED) improves one flagged account or group. Deleting a draft extracted from a statement also flags it, because that row should not have been extracted.
  • No instructions yet: the first posted transaction through an account or group can set baseline instructions, even without corrections.
  • Account corrections teach Bookbot, not Extractor Bot. When Bookbot is installed, it re-checks other pending drafts that received the same account.
  • Older books: instructions in the earlier agent_parser_* properties, and in the legacy agent_prompt, agent_prompt_transaction, agent_prompt_transactions, and agent_prompt_file properties, move to the matching extractor_prompt_* properties the next time Extractor Bot uses the account or group.

AI allowance behavior

Extractor Bot uses Bkper AI: Gemini Flash for extraction and learning, Gemini Flash Lite for small tasks such as classification, and the decision model for comparisons. Automatic extraction uses the allowance of Extractor Bot's installation; API calls use the allowance of the signed-in user. For Business and Professional subscriptions, the allowance may be shared across the domain. The Bkper AI usage dashboard shows the usage attributed to Extractor Bot; account suggestions are attributed to Bookbot.

When the allowance is exhausted:

  • extraction fails without creating partial drafts;
  • Extractor Bot does not switch to another model provider;
  • invoice learning is skipped;
  • statement learning stays flagged for a later audit.

Configuration

Properties
Property Set on Description
extractor_prompt_transaction Account, group Extraction instructions for invoices and receipts
extractor_prompt_transactions Account, group Extraction instructions for statements and CSVs. Learned statement instructions are appended here
extractor_prompt_file Account, group Instructions for file-level properties, such as invoice numbers, statement periods, or bank names
extractor_url_transaction Account, group, book External service for invoices and receipts
extractor_url_transactions Account, group, book External service for statements and CSVs
extractor_url_file Account, group, book External service for file-level properties
agent_excluded_properties Account, group, book Comma- or whitespace-separated property keys left out of extraction comparison and learning. Bookbot also honors it when copying properties

Extractor Bot uses the first non-empty value from the account, then its first group with a value, then the book; values are not merged.

Properties set under their earlier names (agent_parser_transaction, agent_parser_transactions, agent_parser_file, agent_parser_url_transaction, agent_parser_url_transactions, agent_parser_url_file) keep working; the new name wins when an account, group, or book has both. Instructions move to the new names the next time Extractor Bot uses them; parser URLs are never rewritten. Property keys in agent_excluded_properties match case-insensitively and exactly, so category does not exclude category_code.

Example — statement instructions:

extractor_prompt_transactions: |-
  Extract transactions from the statement table.
  - Do not include header rows
  - Include the reference number as a property called "ref"

Example — skip properties that vary per transaction (plain text, not a JSON array):

agent_excluded_properties: "trade_date, settlement_date"
Events handled
Event Behavior
FILE_CREATED Extracts transactions from the uploaded file, asks Bookbot for accounts, and creates drafts
TRANSACTION_CREATED With an attachment, extracts missing fields and file properties from it, asks Bookbot for accounts, and updates the transaction once. Without one, asks Bookbot for accounts and extracts a missing amount or an automatically filled date from the description
TRANSACTION_POSTED Compares posted data with the original extraction and improves instructions when it was corrected
TRANSACTION_UPDATED Same as TRANSACTION_POSTED
TRANSACTION_DELETED Flags the source account or group when a draft extracted from a statement is deleted
BOOK_AUDITED Improves statement instructions for one flagged account or group
Supported file types
Format Extensions
CSV .csv
PDF .pdf
Images .jpg, .jpeg, .png, .bmp, .webp
External extraction services

A parser URL property replaces built-in AI extraction for its purpose:

  • extractor_url_transaction — the service returns data.transaction for invoices and receipts.
  • extractor_url_transactions — the service returns data.transactions for statements and CSVs.
  • extractor_url_file — the service returns file.properties for file-level properties.

The URL is looked up on the account, then its first group with a value, then the group the file was uploaded to, then the book. The service receives a POST with the base64 file content, book metadata, and the account context when available, plus the group context when the URL is set on a group. One endpoint can serve several purposes; Extractor Bot reads only the section for the configured purpose.

Each statement transaction can include book_id to record it in another book, and account_name to assign it to an account by name. A name not found in the target book records the row without that account.

See the external extraction service contract for the request and response formats.

Transaction and file metadata

Extractor Bot stores internal properties (suffixed with _) on drafts for learning and traceability:

Property Description
extractor_extracted_ Original extraction (JSON), compared with the posted transaction to detect corrections
extractor_file_id_ ID of the source file, linking statement drafts to their document
bookbot_* (earlier agent_credit_account_id_, agent_debit_account_id_, agent_description_part_, agent_discovered_properties_) Bookbot's suggestions, kept so Bookbot can re-check drafts after a correction

Drafts recorded before these names existed keep agent_extracted_ and agent_file_id_, and are still read.

On the file, extractor_transactions_summary (earlier transactions_summary) lists, per target book and account, the expected number of non-zero transactions and the IDs of the drafts created. Zero-amount drafts are created but not counted, so a file with only zero-amount transactions gets no summary. ID order is not significant. Only Extractor Bot writes this property; external services cannot set it.

API access

Endpoints and examples

Apps, scripts, and agents can extract transactions from documents and descriptions through the public API, without recording anything in the book.

Production: https://extractor-bot.bkper.app
Preview:    https://extractor-bot-preview.bkper.app
OpenAPI:    https://extractor-bot.bkper.app/openapi.json

All requests require a Bkper OAuth bearer token for a user with view access to the book and to any other book an extraction targets; no installation is required. The API never writes: results are unrecorded drafts without transaction IDs, and it does not find accounts.

Operation Route Effect
Extract transactions POST /api/v1/parse Returns extracted drafts and file properties, without changing the book

Send a file, a transaction, or both:

  • A file is a file already in the book (id) or base64 content; its type is detected as for uploads. Its account_id property selects the account whose instructions and side apply; files uploaded with an account selected already have it.
  • A transaction alone supplies a description, or an attachment, to extract a missing amount and date from.

The response lists transactions, each with its target bookId, optional fileProperties, and an outcome: parsed, empty, or error. Valid requests return HTTP 200 even when extraction fails, so check outcome and error.code, such as FORBIDDEN or usage_limit_exceeded. Malformed requests return HTTP 400.

To record the results, ask Bookbot's API for accounts, then create the drafts in each returned bookId. Keep the returned extractor_extracted_ and extractor_file_id_ properties so Extractor Bot, when installed, can learn when the drafts are posted.

Avoid duplicate drafts: when Extractor Bot is installed, uploading a file already records its drafts, so do not also record API results for that file. The API does not skip files that already have extractor_transactions_summary or transactions_summary; check those properties first.

Minimal extraction example:

# Run `bkper auth login` first if needed
TOKEN="$(bkper auth token)"

curl -X POST \
  -H "Authorization: Bearer ${TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{ "bookId": "<book-id>", "file": { "id": "<file-id>" } }' \
  https://extractor-bot.bkper.app/api/v1/parse

Agents and scripts using the Bkper CLI can send the same request as the signed-in user with bkper app api request extractor-bot /api/v1/parse -d '<json>', or pipe larger bodies, such as base64 files, through stdin.

See the OpenAPI specification for complete request and response schemas.

Learn more