FlowParse
Guide September 2026 22 min read

How to add document extraction to a Retool or Bubble app

Eight steps for a citizen developer or small team to add a document extraction API to an internal tool built in Retool, Bubble or Airtable — from the first test call to a working, bound UI.

FlowParse
flowparse.io

This takes an afternoon, not a sprint

Most internal tools that need to read a document reach for this feature last — after the core app already works, once someone realizes a PDF or a receipt needs to become data before the rest of the tool is useful. The good news is that adding it is small work, precisely because the hard part — classifying and reading the document — is handled entirely by the API. What's left is integration: connecting the call, binding the result, deciding what happens when a field comes back uncertain.

This guide walks through that integration as eight concrete steps, with a dedicated section for each of Retool, Bubble and Airtable's specific connection mechanics further down. None of the steps assume a particular document type or a particular scale — the same eight steps apply whether you're building a first pilot for a single team or extending an existing internal tool to read a new kind of document.

Read through all eight once before starting, even the ones that look obvious — the sequencing matters more than any individual step, and skipping ahead based on a skim tends to be exactly where the mistakes covered later in this guide creep in.

FlowParse
flowparse.io

1. Decide what documents your app actually needs to read

List the specific document types your tool will handle — an invoice, a receipt, a bank statement — rather than a vague "documents" requirement. This matters because a document type determines which fields you'll bind in step 5, and defining it upfront avoids building a generic upload feature nobody in your team actually asked for.

A quick, practical way to build this list: look at whatever your team is currently doing manually with these documents — retyping a total into a spreadsheet, copying a vendor name into an email — and start with exactly that document type first, rather than trying to cover every possible future document on day one.

It's worth writing this list down somewhere visible, even briefly, rather than keeping it in your head — it becomes the reference point for step 3's test documents and step 6's confidence threshold, and a written scope is much easier to defend later if someone asks why the tool doesn't yet handle a document type you deliberately left out.

2. Get an API key and test with /validate

/validate is free on every plan and confirms the exact response shape — field names, nesting, types — before you spend anything on real extraction. This is the step where you decide, concretely, which fields your app will bind to, using the same JSON shape a real call will return.

a minimal shape check
curl -X POST https://flowparse.io/api/v1/validate \
  -H "Authorization: Bearer pf_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{ "type": "invoice", "data": { "vendor_name": "Test Vendor",
        "invoice_number": "TEST-1", "total": 100.00, "currency": "USD" } }'
# → { "valid": true, "issues": [] }

3. Run /extract on real documents

Send five or ten real documents your app will actually receive — not clean examples found online. Include at least one that's genuinely messy: a phone photo, a slightly crooked scan, a document from a source your team doesn't control the quality of. A pilot that only ever sees ideal documents produces false confidence that evaporates the first time a real edge case shows up after launch.

Record the confidence scores from this small batch — this becomes your baseline for step 6's threshold decision, and it's far more useful than guessing at a reasonable number without ever having seen real output.

If your team has documents from more than one source — different vendors, different employees submitting receipts — try to include at least one from each in this test batch. Real variety in this small sample tends to surface issues far earlier than testing exclusively against whichever documents happened to be easiest to find.

4. Add the REST resource or API Connector in your app builder

Every app builder this guide covers has a documented, no-code way to add an external REST API — a resource in Retool, a connector in Bubble, a script or automation step in Airtable. Detailed steps for each are further down this guide; the common thread is configuring your API key once, in one place, rather than embedding it in every individual call.

This step is usually the one that surprises people most — it's genuinely a few minutes of configuration, not a development task. If it takes longer than that, it's almost always because of a header formatting issue (a missing "Bearer" prefix, an extra space) rather than anything conceptually difficult about the connection itself.

FlowParse
flowparse.io

5. Bind the response to a table or form

Map the fields from step 1's document type — vendor, total, date — directly to the table columns or form inputs your app already has. Because the response is already typed, this is usually the fastest step in the whole build: no parsing, no type conversion, just a direct mapping.

Pay particular attention to line items if your document type has them — most app builders' table components can bind directly to an array in the response, turning a nested JSON structure into rows without extra transformation logic.

6. Add a confidence threshold and a review state

Decide which confidence score lets a value pass straight through versus needing a human look. Start conservative — a relatively high threshold, like 0.95 — and lower it gradually as you observe which fields are genuinely reliable on your real document volume.

A workable first version of this review state is often nothing more than a boolean field — "needs review" — set from a simple conditional that checks whether any field's confidence falls below your threshold, and a filtered table view showing only those records. This is enough to start; a more polished review interface can come later.

Resist the urge to set the threshold based on a gut feeling rather than the data from step 3 — a threshold chosen without looking at real confidence scores tends to be either too loose, letting genuinely uncertain values through, or too tight, sending nearly everything to review and defeating the purpose of automating the tool in the first place.

FlowParse
flowparse.io

7. Handle errors inside your workflow

Add an explicit path for a document the API genuinely can't process — a corrupted file, an unsupported format — so your app shows a clear message instead of a silent failure or a blank form. Most app builders make this a straightforward conditional on the API call's error response, the same pattern used for handling any other external API failure.

flowparse.iono audio needed
0:00 / 0:00

8. Ship it and watch usage for the first month

Once live, keep an eye on two things: the share of documents landing in your review state, and any recurring error pattern. Both together tell you whether the confidence threshold from step 6 is calibrated well for your real usage, or whether a specific document source needs a closer look.

A five-minute monthly check — how many documents went through, how many needed review, any repeated errors — is usually enough for an internal tool at this scale. There's no need for elaborate monitoring; the goal is catching a drifting pattern before it becomes a data-quality problem someone else notices first.

Retool in more detail

Under Resources, add a REST API resource with base URL https://flowparse.io/api/v1 and an Authorization header set to Bearer YOUR_API_KEY. Create a query against that resource for POST /extract, passing the file from a File Button or File Dropzone component's base64 value as the request body. Bind the query's result directly to a Table component's data property, or to individual form inputs using the query's dot-notation path to each field.

A useful Retool-specific detail: set the query to run "on click" rather than automatically on page load, so the API is only called when a user actually submits a document rather than every time the app re-renders — a common source of unexpected usage for builders new to Retool's query triggers.

Bubble in more detail

In the API Connector plugin, add a new API with the extraction endpoint, set the Authorization header with your key, and configure the call as a POST with a body parameter for the file. Use Bubble's "initialize call" feature against a real test document so Bubble automatically detects the response fields as dynamic data types. From there, a workflow triggered on file upload can call the API and create or modify a Thing directly from the response.

One Bubble-specific gotcha worth knowing in advance: the "initialize call" step needs a real document, not a placeholder value, for Bubble to correctly infer nested fields like a line-item array — running it against an empty or fake payload often produces a flattened, less useful field list than the real response actually has.

Airtable in more detail

The Scripting app can fetch the endpoint directly with a standard JavaScript fetch call, read the JSON response, and write fields back to the current record — a single script handles the entire round trip. For a fully automated version, an Automation with a "When record is updated" trigger on an attachment field, followed by a "Run a script" action, achieves the same result without a person needing to run the script manually.

Common mistakes in this build

The most common mistake is skipping step 6 entirely and treating every extracted value as correct from day one — even at strong accuracy, some documents are genuinely ambiguous, and a tool that doesn't catch those risks a wrong value quietly entering a record nobody double-checks. The second most common mistake is testing only with clean example documents in step 3, which produces a confidence baseline that doesn't hold up once real, messier documents from actual users start arriving.

A third, subtler mistake is binding fields too rigidly — hardcoding an assumption that every document will have exactly the fields tested in step 3, rather than handling the case where a genuinely unusual document returns a field as empty or missing. A small default or fallback in your app's binding logic avoids a broken UI the first time a document doesn't match the expected shape exactly.

A fourth mistake, more about process than code: not writing down why the threshold was set where it was. Six months later, with the original builder possibly having moved to a different project, nobody remembers whether 0.93 was a careful decision or an arbitrary starting point — a one-line note at the time it's set saves real confusion later.

FlowParse
flowparse.io

How long each step takes

StepTypical time
1–3 (define, validate, test)30–60 minutes
4–5 (connect, bind)30–90 minutes
6–7 (threshold, error handling)30–60 minutes
8 (launch, monitor)Ongoing, a few minutes a month

These figures assume a single document type on a first pass — adding a second type later, once the pattern is established, is typically faster than the first, since steps 4 through 7 mostly reuse infrastructure already built rather than starting from a blank canvas.

A full worked build, start to finish

A small ops team building an internal expense-approval tool in Retool defines a single document type — receipts (step 1) — and tests the response shape on /validate (step 2). A batch of 15 real receipts, including three phone photos, comes back with 13 above 0.95 confidence and two flagged lower, both slightly blurry (step 3). A REST resource and query are added in an afternoon (step 4), bound directly to an expense table (step 5), with a 0.93 confidence threshold and a filtered "needs review" view (step 6). A simple error banner handles unreadable uploads (step 7). The tool ships to five people on the team; after the first month, 4% of receipts land in review, consistently the ones photographed in poor lighting — a number the team decides is acceptable without further tuning (step 8).

Total elapsed time from first opening the API docs to a working tool live for the whole team: about four hours, spread across a single afternoon rather than a dedicated project. None of the eight steps required backend code, and the team's only ongoing task since launch has been the occasional glance at the review queue during their existing weekly team check-in.

Doing this solo versus with a small team

A solo builder follows the same eight steps compressed into their own time rather than split across roles — defining scope, testing, building and reviewing threshold decisions all fall to one person, which if anything makes step 3's real-document testing more valuable, since there's no second pair of eyes to catch a threshold set too loosely. A small team can split roles roughly along the steps — one person handling the technical connection (steps 2–5, 7), another closer to actual document volume setting the threshold (step 6) — which tends to produce a threshold better matched to real risk tolerance than a purely technical guess.

Neither approach is objectively better — a solo builder moves faster with fewer handoffs, while a small team distributes the judgment calls across more perspective. What matters more than which structure you use is that someone, explicitly, owns the confidence threshold decision rather than it being an unowned default nobody remembers setting.

A printable checklist

Use this to sanity-check a build before showing it to anyone else on the team, or to pick up cleanly where you left off if a few days pass between working sessions.

Document types explicitly defined, not left generic (step 1)

Response shape confirmed for free on /validate (step 2)

Real documents tested, including at least one messy one (step 3)

REST resource or API Connector configured in the app builder (step 4)

Fields bound directly to a table or form (step 5)

Confidence threshold set and a review state built (step 6)

Error path handled for unreadable documents (step 7)

Usage and review rate checked after the first month (step 8)

Print or copy this list at the end of step 7, right before launch — it's deliberately ordered to match the eight steps above, so working through it top to bottom doubles as a final review of the whole build rather than a separate task.

What changes if usage grows

Nothing in the integration itself needs to change — the same call handles ten documents a week or a thousand, since pricing and capacity are consumption-based. If the tool eventually needs to process a genuine batch of documents at once, rather than one per user action, looping the same call with a modest concurrency setting is the only addition required; the response shape and binding logic stay identical.

This flat scaling property is worth appreciating explicitly, since it's the opposite of what usually happens when a homegrown solution meets real growth — a custom parser tends to need rearchitecting as volume rises, while a stateless API call simply gets called more often, with nothing about the integration itself needing to change.

Who this guide is for

Citizen developers and small teams building an internal tool in Retool, Bubble, Airtable or a similar app builder, who need document data inside their own app rather than a separate automation system reacting to external events.

It's equally useful for someone maintaining an existing internal tool who's never added document handling before, and for a product manager scoping out whether a proposed feature is actually as much work as it sounds — the eight steps here double as a reasonably accurate estimate of the real effort involved.

It's written to be equally useful whether this is your first time connecting an external API to an app builder at all, or your tenth — the platform-specific sections further down are there precisely so an experienced builder can skip straight to the mechanics without re-reading the conceptual steps they already know.

A short glossary

TermMeaning here
Confidence thresholdThe score below which a field is routed to review instead of passing through automatically
Review stateA flag or filtered view showing records needing a human look
Synchronous callA request that returns its full result in the same response, with no polling
BindingMapping a value from an API response directly to a UI component

Keep this glossary close to wherever your team documents the tool itself — a README, a wiki page, a comment at the top of the workflow — so the terminology stays consistent for whoever touches the integration next.

One habit worth keeping after launch

Once the integration is stable, the single habit worth keeping is the monthly glance at review rate and error patterns from step 8. It costs a few minutes and is the earliest sign that a new document source or format has entered the mix and is worth a look — far cheaper to catch there than after a colleague notices a wrong value in a record they trusted.

Beyond that, resist the urge to keep tweaking a working integration. A confidence threshold, a binding and a review state that are functioning don't need continuous attention — build them once, check in monthly, and spend the rest of your time on the parts of the app that actually differentiate it.

If you take one thing from this guide beyond the eight steps themselves, make it this: the parts that feel like they deserve the most attention — connecting the API, writing the binding — are genuinely the fast parts. The parts worth actually thinking carefully about are the ones easy to rush past: which documents you scope in at step 1, and where you set the threshold at step 6. Get those two right and the rest of this guide is mostly mechanical.

Frequently asked questions

Start with step 2

Get a free API key and confirm the response shape on a real document before you build anything else.

Keep reading