FDD Item 19 Parser — Franchise AUV & Financial Performance avatar

FDD Item 19 Parser — Franchise AUV & Financial Performance

Pricing

from $600.00 / 1,000 parsed fdds

Go to Apify Store
FDD Item 19 Parser — Franchise AUV & Financial Performance

FDD Item 19 Parser — Franchise AUV & Financial Performance

Search state franchise registries (Minnesota CARDS + Wisconsin DFI), download Franchise Disclosure Document PDFs, and extract Item 19 Financial Performance Representations — has-FPR flag, raw Item 19 text, every dollar figure, and best-effort average/median/high/low unit volume. No logins.

Pricing

from $600.00 / 1,000 parsed fdds

Rating

0.0

(0)

Developer

Esteban Ortega

Esteban Ortega

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 hours ago

Last modified

Share

FDD Item 19 Parser — Franchise AUV & Financial Performance Representations

Extract Item 19 (Financial Performance Representations) and the average unit volume (AUV) from Franchise Disclosure Documents (FDDs) — automatically. This actor searches the official Minnesota CARDS franchise registry, downloads the FDD PDF, and returns the Item 19 section as structured data: a has_fpr flag, the raw Item 19 text, every dollar figure, and — for simple summary tables — the headline average / median / high / low unit volume. No CAPTCHAs, no logins, no API keys.

Clean provenance, by design. Every number traces to a public state-government filing you can open yourself — no paywall scraping, no gray-area data. That's the provenance standard lenders, brokers, and franchise attorneys actually need.

Built for franchise researchers, franchise brokers, franchise-buyer due-diligence, and anyone building a dataset of franchise earnings claims.

What it does

Give it a franchise name (e.g. Jersey Mike's) or a year + document-type sweep. For each franchise name it will:

  1. Search the Minnesota CARDS franchise registry — full search, complete filing history, and stable per-document PDF links.
  2. Download only the newest full FDD for that name (newest complete document — Clean/Final/Revised FDD; a Marked redline only when nothing complete exists) — never the whole filing history. In sweep mode (a year with no names) it downloads matching FDDs up to maxFdds.
  3. Locate Item 19 using a longest-span sectioner that reliably picks the document body (not the table-of-contents stub) even when Item 19 is cross-referenced in state addenda.
  4. Parse the Financial Performance Representation: presence flag, raw text, all dollar figures, a best-effort headline AUV for single-summary-row tables (Jersey Mike's style), and a complex_table_flag for multi-quartile grids (Anytime Fitness style) that it deliberately does not mis-parse.

Coverage: one registry, on purpose

This version queries Minnesota CARDS only (states: ["MN"] — the only supported value). An FDD is a single national document, and Minnesota is the registry that exposes the most of it over plain HTTP: name search, the full filing history per franchisor, year sweeps, and stable PDF URLs. Support for a second registry (Wisconsin DFI) is planned for a later version. California and NASAA EFD are excluded because they block automated HTTP access.

Note that CARDS matches franchiseName by substring, so a short search string can select a franchisor you did not have in mind (searching Papa returns Beard Papa's). The franchisor and franchise_name fields on every record tell you exactly which one you got.

Only real FDDs are downloaded — and billed

A CARDS search returns amendments, consents, deficiency notices and cover letters alongside the disclosure documents. Only genuine full-FDD document types (Clean FDD, Final FDD, Revised FDD, Marked FDD) are ever downloaded and charged as an fdd record. If a search matches rows but none of them is an FDD, nothing is downloaded, nothing is billed, and an unbilled diagnostic says so.

Nothing you asked for disappears silently

Every requested franchise name ends the run accounted for — by a billed record, or by an unbilled diagnostic in the run log and status message:

DiagnosticMeaning
no_results_foundSearched; the registry returned nothing for that name.
no_fdd_document_in_resultsSearched; rows came back but none is a full FDD document type, so nothing was billed in its place.
already_delivered_under_earlier_queryIts only document was already delivered under an earlier name, so it was not re-billed. The diagnostic names the record that covers it.
budget_exhausted_name_not_searchedThe maxFdds budget ran out before this name was searched at all. The diagnostic says what to raise maxFdds to.
duplicate_franchise_name_collapsedThe name repeats an earlier entry (case- or whitespace-variant), so it was searched and billed once.
mn_search_skipped_no_criteriaNeither franchiseNames nor year was given; an empty-criteria sweep would have billed arbitrary FDDs.
franchise_names_all_blankfranchiseNames was supplied but every entry is blank/whitespace. Nothing is searched or billed — the run never reinterprets that as a year sweep. Set franchiseNames: [] to run a sweep deliberately.
unsupported_state_ignored / no_supported_state_selectedA saved input asked for a state other than MN; it was not searched, and it is named rather than quietly dropped.
search_failed / download_failed / not_a_pdfAggregated failure count and first error for that name.

None of these is written to the dataset, so none of them is billed.

Output fields

One record per downloaded FDD (type: "fdd"). Every record carries the same key set (rectangular CSV/XLSX exports):

{
"type": "fdd",
"state": "MN",
"sources": ["MN CARDS"],
"states": ["MN"],
"scraped_at": "2026-07-27T00:00:00+00:00",
"franchisor": "A SUB ABOVE, LLC",
"franchise_name": "JERSEY MIKE'S",
"mn_file_number": "9229",
"document_type": "Clean FDD",
"filing_year": "2026",
"received_date": "04/10/2026",
"pdf_url": "https://cards.web.commerce.state.mn.us/documents/{GUID}/download?documentClass=FRANCHISE_REGISTRATIONS&contentSequence=0",
"pdf_bytes_kvs_key": null,
"has_fpr": true,
"item19_status": "extracted",
"item19_text": "ITEM 19. FINANCIAL PERFORMANCE REPRESENTATIONS ...",
"item19_char_count": 5824,
"dollar_figures": ["$1,367,578", "$1,305,850", "$3,228,616", "$512,332"],
"headline_auv": {
"average": "$1,367,578",
"median": "$1,305,850",
"high": "$3,228,616",
"low": "$512,332"
},
"complex_table_flag": false,
"source_url": "https://cards.web.commerce.state.mn.us/documents/{GUID}/download?...",
"source_urls": [
"https://cards.web.commerce.state.mn.us/documents/{GUID}/download?..."
],
"error": null
}

Provenance fields, present and non-empty on every record:

FieldMeaning
stateThe state whose document this record's Item 19 came from — always MN in this version.
sourcesRegistries that contributed to this record: ["MN CARDS"].
statesThe states behind sources: ["MN"].
source_urlsEvery contributing URL — the FDD PDF URL for an fdd record, the CARDS search URL for a diagnostic.

Every record — fdd and summary alike — carries the identical full key set in the identical order. Beyond the example above that also includes document_title, pdf_title, source, and the summary-record fields query, fdds_found, and failed_count.

has_fpr never asserts what the parser doesn't know. It is tri-state: true / false are reported only when the Item 19 section was actually located in the document; otherwise it is null (unknown) and item19_status says why:

item19_statusMeaning
extractedThe Item 19 section was located; has_fpr is a real true/false and the item19_* fields are populated.
section_not_foundThe PDF's text was extracted but no ITEM 19 → ITEM 20 span was found (unusual layout or heading wording). has_fpr is null — this is not a claim that the franchisor makes no FPR.
no_text_extractedThe PDF yielded no text at all (typically a scanned image without a text layer). has_fpr is null.
parse_failedText extraction/analysis raised an error; error carries the detail. has_fpr is null.

Search and download failures are not billed at all. A failed search or a failed/non-PDF download never produces an all-null fdd record, never consumes the maxFdds budget, and is never written to the dataset. Failure diagnostics (aggregated to at most one per requested name, with failed_count and the first error string) and the non-failure notices in the table above are routed to the run log and the run status message instead of billed dataset items. The dataset contains fdd records and nothing else.

Records stream. Each record is pushed to the dataset the moment it is produced — nothing is buffered across franchise names — so a run that times out or migrates late still delivers everything scraped so far.

Input

FieldTypeDescription
franchiseNamesarrayFranchise/franchisor names to search (e.g. ["Jersey Mike's", "Anytime Fitness"]). Per name, only the newest full FDD is downloaded — normally one record per name. Repeated or whitespace-variant entries are collapsed, and two names resolving to the same document are billed once.
yearstringSweep mode: pull a batch of FDDs filed in this year (e.g. 2026). When combined with franchiseNames, restricts each name's results to that filing year.
documentTypestringRestrict to a document type. Unset means Clean FDD — the complete disclosure document, best for Item 19. Pass "" for "Any document type"; even then only full-FDD document types are downloaded.
statesarray["MN"] — Minnesota CARDS is the only registry this version searches.
maxFddsintegerSingle global cap on FDD PDFs downloaded + parsed per run, across all names. One downloaded PDF is one billed record, so this is also your hard cost cap. Failures don't count against it. If it runs out before every name is searched, the unsearched names are named in the log. Default 3.
downloadPdfToKvsbooleanAlso store each raw PDF in the run key-value store (pdf_bytes_kvs_key).
requestDelaySecondsintegerPoliteness delay between requests (default 2s).
proxyConfigurationobjectDatacenter proxy is sufficient (public government site).

Use cases

  • Franchise due diligence — pull the earnings claims for a shortlist of franchises before buying.
  • Franchise-broker research — compare unit volumes across concepts in the same category.
  • Franchise earnings datasets — bulk-collect Item 19 text + dollar figures for analysis or an LLM pipeline.
  • Competitive benchmarking — track a franchisor's reported AUV year over year.
  • Lead qualification — see which franchises even make a financial performance representation (has_fpr).

FAQ

How do I get Item 19 financial data from an FDD without reading 500 pages?

Point this actor at a franchise name; it downloads the FDD and returns just the Item 19 section plus the extracted dollar figures and headline average/median/high/low.

What is the average unit volume (AUV) of a franchise, and where is it in the FDD?

AUV is the average revenue of a brand's units — the headline number of franchise due diligence. It lives in Item 19 of the FDD, when the franchisor chooses to disclose it (roughly two-thirds now do). This actor returns it as headline_auv with the average, median, high, and low, verified against the table's own column order. Always read the footnotes too: brands define AUV differently (company-owned units in or out, top-quartile only, etc.) — which is why the full item19_text ships with every record.

How do I compare Item 19 earnings claims across multiple franchises?

Pass several names in franchiseNames — each returns its newest complete FDD's Item 19 in one run, one record per brand, with identical fields. Export to CSV/XLSX and you have a side-by-side AUV benchmark.

Is franchise Item 19 data public?

Yes. Franchisors must register their FDD in registration states, and Minnesota's CARDS registry publishes the full documents. Every record this actor returns links the exact government-hosted PDF it parsed.

How much does franchise Item 19 data cost elsewhere?

FRANdata charges about $220 for a single-FDD report; Franchimp Pro is $167/month. This actor is $0.60 per parsed FDD — the same Item 19 numbers, from the same public filings, with a source PDF link on every row.

Which franchises even make a financial performance representation?

That's the has_fpr flag. It's tri-state and honest: true (section found, real FPR), false (section found, franchisor declines), or null (section couldn't be located — see item19_status). Screening a list of brands by has_fpr is the fastest first-pass filter in franchise due diligence.

Which states does it cover?

Minnesota (CARDS) only in this version. FDDs are national documents and most franchisors register in Minnesota, so franchise coverage is broad even from a single registration state. A second registry (Wisconsin DFI) is planned for a later version; California and NASAA EFD are excluded because they block automated HTTP access.

Why did a name I asked for return no record?

Check the run log. Every name that produced no record produces a diagnostic saying which of these happened: nothing matched, the matches were not FDDs, the document was already delivered under an earlier name, the name repeated an earlier entry, or the maxFdds budget ran out before it was searched. None of those is billed.

Does it need an API key or login?

No. The source is a public state-government franchise registry served over plain HTTP.

What does has_fpr: null mean?

The document was delivered but the Item 19 section could not be located or parsed — see item19_status for the reason. null means unknown, deliberately distinct from false ("the section was found and the franchisor declines to make an FPR"). Treat null records as "read the PDF yourself", not as "no earnings claim".

Which FDD does it pick when a franchise has several filings?

The newest complete disclosure document: Clean FDD, Final FDD, or Revised FDD - Clean, newest filing year first. Redlines (Marked FDD, Revised FDD - Marked Up) may contain only the changed pages, so one is returned only when no complete document exists at all.

What is a "complex table" flag?

Some franchisors (e.g. Anytime Fitness) publish Item 19 as a multi-column quartile grid. Reconstructing every cell's column with text extraction alone is unreliable, so the actor flags these (complex_table_flag: true) and returns the raw text and all dollar figures rather than guessing a headline number.

How accurate is headline_auv?

It is extracted only when a single clean summary row is present (count + average + median + high + low), verified against the table header's column order. For complex/quartile tables it returns all-null and sets complex_table_flag.

Pricing

$0.60 per parsed FDD — versus ~$220 per single-FDD report at FRANdata or $167/month at Franchimp. The parsed-Item-19 layer as structured data, for cents on their dollar, with cleaner provenance.

This actor is billed per result (per FDD record returned). One downloaded FDD PDF is exactly one billed record, so maxFdds — a single global budget across all names — is a hard cost cap. Only genuine full-FDD document types are ever downloaded, so you are never charged for an amendment or a deficiency notice. No document is billed twice within a run, whether two names resolve to the same document or the same name is listed twice. Failed searches/downloads are never billed and never consume the cap: diagnostics go to the run log and status message, not the dataset.

A record with item19_status other than extracted (rare — unusual layout, scanned image, parse error) is still one billed result: the FDD was found, downloaded and delivered with its full registration metadata and PDF link, and has_fpr is honestly null rather than a guessed false.

Notes on the source

  • Minnesota CARDS (cards.web.commerce.state.mn.us) — search + 500-row pages + stable per-document PDF URLs. Full filing history. Franchise names match by substring.
  • The actor honors polite request delays and never attempts CAPTCHA or WAF evasion; a blocked source is reported, not bypassed.