Excel to JSON Converter for XLSX Workbooks
Pricing
$10.00 / 1,000 workbooks
Excel to JSON Converter for XLSX Workbooks
Convert authorized XLSX workbooks into typed JSON sheets with stable headers, row numbers, dates, formula caches and explicit whole-workbook limit notices.
Pricing
$10.00 / 1,000 workbooks
Rating
0.0
(0)
Developer
Tim Zinin
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
a day ago
Last modified
Categories
Share
Convert authorized XLSX workbooks into typed JSON sheets with stable headers, row numbers, dates, formula caches and explicit whole-workbook limit notices.
Evidence status (2026-09-05). The actor was built on the Apify platform (build B0lue1YCceqsfTJH9), its pay-per-event tariff was read back from the platform, and four private acceptance runs on Apify infrastructure produced the rows shown in this document: a two-sheet typed workbook, an empty workbook, a workbook refused at maxCells=1 and a 1904-date-system workbook.
R1. What you get
Convert an authorized XLSX download into typed JSON with sheet names, stable column headers, physical row numbers, date-system handling and distinguishable formula expressions and cached values. The useful record contains the complete selected workbook result. Strings, numbers and booleans remain different JSON types; dates and formulas carry explicit type information so a consumer can distinguish a date value from an ordinary date-looking string.
The converter does not launch Excel, recalculate formulas, execute macros, refresh external links or reproduce formatting. It accepts XLSX packages with the documented bounded structure. Legacy XLS, binary XLSB, macro-enabled XLSM and encrypted workbooks are outside this contract. A file's .xlsx suffix is not enough: the download must have an acceptable MIME, ZIP signature and valid bounded workbook parts.
The full workbook is validated before any workbook result is billed. A partially streamed or oversized book becomes a free limit/error notice with no nested partial workbook offered as success. Selecting one sheet controls output, while the whole source still has to satisfy ZIP, worksheet and nonempty-cell limits.
R2. Who uses it
Data operations teams can convert reports supplied by an authorized business system into a repeatable JSON import. Developers can ingest controlled XLSX uploads without running a desktop spreadsheet application. Report owners can inspect the exact distinction between raw typed values, formulas, stale or missing caches and merged-cell gaps before feeding a workbook into another data pipeline.
A suitable recurring workflow has a clear workbook owner, stable sheet selection and a known header row. It checks a representative file whenever the producing system changes its export layout. A one-time migration can use the actor to expose the workbook structure and row coordinates, then apply its own mapping into a destination schema. The actor does not infer which sheet represents revenue, customers or transactions.
Use a separate product or preparation step if you need macros, formula evaluation, chart rendering, visual layout reconstruction, password handling or arbitrary workbook sizes. If a formula result must be current, the owner needs to recalculate and save an authorized copy in the source spreadsheet system before conversion; a cached value alone is not evidence that a formula was recalculated recently.
R3. How to run
Choose Try, inspect the input form, keep the small fixture prefill for your first check, and select Start. After the run, open Dataset for records and the default key-value store's OUTPUT record for the summary. Download JSON if you need to preserve nested arrays, numeric values, booleans and nulls. A spreadsheet export can hide those distinctions, so use CSV as a presentation format rather than the authoritative conversion archive.
Replace the fixture URLs with direct public HTTP or HTTPS download URLs for files you own or are authorized to process. A document viewer URL, cloud-drive preview or login page is not necessarily a download. Test your final URL without your browser's authenticated session. This actor sends no browser cookies and accepts no username/password URL. If a file service requires a signed query string, keep the run and output private: source URLs are included in provenance and may expose that temporary access link to anyone who can read the dataset.
Keep input and result limits small until a representative file succeeds. Then save the exact input as a task. A task stores configuration; it does not change the actor's hard safety bounds. For recurring work, connect that task to Apify's existing scheduling feature and choose a frequency that matches your document publication cycle. The actor does not create schedules, messages, tickets or workflows on your behalf.
Inspect both useful records and free notices before adding automation. A successful process status is not a count of useful documents. Conversely, a run that later fails can retain useful records already delivered. Save the run ID, build version, input, dataset ID and OUTPUT summary together so a colleague can reconcile the actual observation without inferring it from a screenshot or a file name.
The prefill is xlsx-types.xlsx with maxCells50000, sheetNames[] and headerRow1. It contains a Types sheet and a small Summary sheet. It deliberately includes blank and duplicate headers, a date, a boolean, a formula cached as85, another formula without a cached result and a merged range. These cases make the first dataset inspection more useful than a workbook containing only plain text.
For your own file, identify the physical row that contains column headings and enter it as headerRow. Leave sheetNames empty to output all sheets, or supply exact names to select a subset. A missing requested name is an error rather than a silently empty selection. Verify headers and rowNumbers after the run before saving a recurring task.
R4. Pricing
The price is $0 per start + $0.01 per workbook, read back from the platform tariff on 2026-09-05 (apify-actor-start $0, result-found $0.01, model PAY_PER_EVENT). One complete workbook is $0.01, three in one run are $0.03, and100 useful workbooks are $1 before any platform changes. A workbook is the unit even when it contains several sheets or thousands of cells. Empty workbooks, ZIP/format errors and all incomplete or over-limit workbooks have no result event. Those arithmetic examples are not receipts.
The primary paid unit is one complete XLSX workbook, with selected sheets and rows nested in a single result. A complete useful record is delivered with one named result-found event in the same Actor.pushData call. There is no separate request to charge a result and no page/cell/text-fragment surcharge hidden inside the record. A free notice has found:false and resultCount:0, and is written without a result event. You can therefore see more dataset rows than paid results.
Platform evidence for the tariff above (charged event counts of the accepted runs): two-sheet typed workbook CCOmwKfJwp1bPriqs result-found: 1; empty workbook iCq6dCJGGvTaanzJM 0; workbook refused at maxCells=1 USt4kwfU3KxaC4UAi 0; 1904-date-system workbook DzXstlMxbR4e5avgp 1. There is no start event in the tariff, so a run start costs nothing and the run memory does not change the cost; the acceptance runs were started with 4096 MB and show no apify-actor-start charge. Keep the default memory unless a large workbook needs more.
At runtime the actor reads actual pricing from the initialized Apify SDK. A platform run with unreadable pricing, no positive result-found price, invalid event prices, or a priced automatic dataset-item event fails closed. The actor will not use an explanatory dataset write if that write could itself be billable. In that situation the explanation is in the run log and failed status. A start event may already exist, so a failure is not a promise of a zero invoice.
The remaining budget is checked immediately before a paid write, inside the same lock as the write. This matters at the boundary: a cap one microdollar below the next complete unit must not be rounded up to buy that unit. Concurrent calls share the lock, and the last paid record still counts if the SDK returns an event-limit flag with its successful write. Subsequent paid work stops; previously delivered records remain available.
If storage or charging fails during a paid write, the result can be uncertain. A row may have reached storage before the charge acknowledgement failed. The actor stops, records deliveryUncertain and fails the run; it does not retry the same row automatically. Inspect the dataset and charged event counters before rerunning that input. There is no persistent replay ledger, so a new successful run can deliver and bill the same file contents again.
Set a run budget independently of input caps. An input cap bounds document processing; a monetary cap bounds additional result events. Neither is a quota for the other. A tiny budget can prevent delivery even when the parser produced useful content, while a large budget does not permit files beyond byte, page, cell, pixel or runtime bounds. Use requested/processed/unprocessed and delivered/paid/free together when explaining that difference to your team.
R5. Input contract
| Field | Prefill | Contract |
|---|---|---|
| fileUrls | ["https://api.apify.com/v2/key-value-stores/b0cgFsJRqVv3XOZyG/records/xlsx-types.xlsx"] | One to three public HTTP(S) direct download URLs of XLSX workbooks you are authorized to convert. No credentials, fragments or private addresses. Prefill is our original two-sheet fixture. |
| sheetNames | [] | Empty selects all sheets; otherwise provide at most five exact worksheet names. Missing names produce a free error. Whole-workbook ZIP and nonempty-cell limits still include unselected sheets. |
| headerRow | 1 | One-based physical worksheet row used for headers. Blank headers become column_N and duplicates receive stable suffixes. Original data row numbers are retained; earlier rows are not output. |
| maxCells | 50000 | Count nonempty stored cells including headers, formulas, preamble and unselected sheets. Reject the entire workbook on overflow; no partial workbook is charged. |
Every field is validated before expensive work. Unknown properties, wrong types and oversized arrays are rejected; numeric strings are not silently coerced to integers. Arrays of source URLs are checked before any multiplicative resource limit. URLs must be absolute, at most2048 characters, HTTP or HTTPS, with no credentials or fragment. Duplicate identical normalized URLs in the same input are processed once; query parameters are retained because they can select a different file or grant access to a particular version.
Private, loopback, link-local and cloud-metadata addresses are refused. This applies to numeric addresses, unusual IPv4/IPv6 spellings, DNS answers and redirect destinations. The connection is pinned to the verified DNS addresses so a second lookup cannot redirect the socket to a private address. A public-looking name is not sufficient evidence that its resolved address is safe. The same transport protects robots requests and the actual file download.
A file can redirect at most five times. Every hop is checked before a connection, and each new origin has its own robots check. The actor follows normal public redirects without adding authentication. It retains the requested URL in input and the final file URL in sourceUrl, with redirect evidence where applicable. If the final destination is private, robots-disallowed or inaccessible, the result is a free error and the last known good downstream record should remain intact.
The download cap is checked against Content-Length when available and against received bytes while streaming. The streaming check is essential: a server may omit the header, advertise a compressed size or provide an incorrect length. The bounded downloader handles bytes directly. It does not run a binary document through a text decoder and then attempt to reconstruct it. All parsers receive the exact downloaded binary buffer after transport-level decompression.
Robots is checked per origin. A404 robots response means no published rules were found; it is not a copyright license. A disallow rule prevents the file request. Invalid, unavailable or blocked robots does not trigger a permissive fallback. File access401/403 is not bypassed. Requests, redirects, retries and robots retrieval share a maximum rate of one request per second per host. Providing more URLs does not increase per-host concurrency.
XLSX-specific bounds: at most3 files,10,000,000 download bytes per workbook,30,000,000 total run download bytes,100,000,000 expanded ZIP bytes,2000 ZIP entries and5 worksheets per source. maxCells accepts1 through50000 nonempty stored cells per workbook, and the file-count product cannot exceed150000 per run. Headers, formulas, preamble rows and unselected sheets all count toward the workbook cell limit.
The ZIP guard scans actual decompression streams and checks sizes and CRC before handing a normalized archive to ExcelJS. It also rejects duplicate/unsafe entries, encrypted entries, unsupported compression, macros, DTD declarations and inconsistent worksheet relationships. XML text is bounded at5MB per text node, depth64 and2million elements per entry; merge metadata is capped50000 ranges. These limits bound parser work as well as final output.
The result must fit5MB. Sparse worksheets can exceed this limit despite having relatively few nonempty cells: a value far to the right creates many missing column positions in a row-shaped JSON result. The converter checks that expansion while building rows and refuses the whole book when the result would be too large. It does not quietly discard the distant column or sell a truncated table.
A separate256MB parser worker handles each file for at most60 seconds within the run deadline. Temporary normalized ZIP and worksheet streams are private scratch files under a unique per-file directory. They are removed when the worker finishes, fails or is terminated. The original downloaded-byte SHA remains the source identity even though a normalized scratch archive is used internally for safe streaming.
R6. Real happy, partial and failure output
The examples below are dataset rows from private acceptance runs executed on Apify infrastructure on 2026-09-05 with the deployed build and the live tariff. They are unedited. The source files are the hosted Wave A fixtures (syntheticFixture:true), generated with fixed control values rather than customer material.
The first JSON block contains the literal production prefill. The blocks after it are the actual rows of the accepted runs, one run per fixture: Examples A and D are paid complete workbooks, Examples B and C are the two free notices.
Every row uses the common envelope: input identifies the request; sourceUrl identifies the response used; found identifies a useful complete paid unit; status gives the domain outcome; resultCount is one for that unit and zero for a notice. error is empty for useful completion and clean absence. It is nonempty for transport, access, format, parser and resource failures. warnings can describe limitations without converting a complete unit into an error.
The row-level partial flag belongs to that row, while OUTPUT.partial describes the run. A run can be partial even though an earlier complete row has partial:false. Do not overwrite the status of a valid delivered unit just because another file failed or remained unprocessed. Equally, do not call the run complete just because one row has found:true. This distinction is what allows a batch workflow to retain useful work while retrying only the missing portion.
{"fileUrls": ["https://api.apify.com/v2/key-value-stores/b0cgFsJRqVv3XOZyG/records/xlsx-types.xlsx"],"sheetNames": [],"headerRow": 1,"maxCells": 50000}
Example A — two-sheet typed workbook, paid (result-found counted once). Run CCOmwKfJwp1bPriqs.
{"input": "https://api.apify.com/v2/key-value-stores/b0cgFsJRqVv3XOZyG/records/xlsx-types.xlsx","sourceUrl": "https://api.apify.com/v2/key-value-stores/b0cgFsJRqVv3XOZyG/records/xlsx-types.xlsx","found": true,"status": "ok","resultCount": 1,"partial": false,"error": "","warnings": [],"checkedAt": "2026-09-05T19:11:52.514Z","schemaVersion": "1.0","workbookId": "e460d0abb319dc6efbfc47b1503256dd9514474dcd9d5d3c0555e1899ba7deb6","sha256": "e460d0abb319dc6efbfc47b1503256dd9514474dcd9d5d3c0555e1899ba7deb6","sheets": [{"name": "Types","headers": ["text","number","date","boolean","formula","column_6","dup","dup_2","merged"],"rows": [{"text": "WAVE-A XLSX TYPE MARKER","number": 42.5,"date": {"type": "date","value": "2026-09-01T00:00:00.000Z"},"boolean": true,"formula": {"type": "formula","formula": "B2*2","cachedValue": 85,"cachedType": "number"},"column_6": "blank-header","dup": "left","dup_2": "merged top-left","merged": null},{"text": "cached-missing","number": 7,"date": {"type": "date","value": "2026-09-02T00:00:00.000Z"},"boolean": false,"formula": {"type": "formula","formula": "B3*2","cachedValue": null,"cachedType": "missing"},"column_6": null,"dup": "right","dup_2": null,"merged": null}],"rowNumbers": [2,3],"mergedRanges": ["H2:I2"]},{"name": "Summary","headers": ["key","value"],"rows": [{"key": "WAVE-A SECOND SHEET","value": 123}],"rowNumbers": [2],"mergedRanges": []}],"dateSystem": "1900","cellCount": 27,"formulaWarnings": ["Types!E3: formula has no cached value; not recalculated."],"syntheticFixture": true,"redirectChain": [],"expandedBytes": 17999,"zipEntries": 11}
Example B — valid workbook without cells, free not_found. Run iCq6dCJGGvTaanzJM.
{"input": "https://api.apify.com/v2/key-value-stores/b0cgFsJRqVv3XOZyG/records/xlsx-empty.xlsx","sourceUrl": "https://api.apify.com/v2/key-value-stores/b0cgFsJRqVv3XOZyG/records/xlsx-empty.xlsx","found": false,"status": "not_found","resultCount": 0,"partial": false,"error": "","warnings": [],"checkedAt": "2026-09-05T19:11:59.005Z","schemaVersion": "1.0","workbookId": "b7734926fa63d6e85c28fbe8f41b21caf85f6e9604be57d278832d56555fb9f9","sha256": "b7734926fa63d6e85c28fbe8f41b21caf85f6e9604be57d278832d56555fb9f9","sheets": [{"name": "Empty","headers": [],"rows": [],"rowNumbers": [],"mergedRanges": []}],"dateSystem": "1900","cellCount": 0,"formulaWarnings": [],"syntheticFixture": true,"redirectChain": [],"expandedBytes": 14689,"zipEntries": 9}
Example C — workbook above maxCells=1, free whole-workbook limit_exceeded refusal. Run USt4kwfU3KxaC4UAi.
{"input": "https://api.apify.com/v2/key-value-stores/b0cgFsJRqVv3XOZyG/records/xlsx-types.xlsx","sourceUrl": "https://api.apify.com/v2/key-value-stores/b0cgFsJRqVv3XOZyG/records/xlsx-types.xlsx","found": false,"status": "limit_exceeded","resultCount": 0,"partial": true,"error": "Workbook nonempty cell limit exceeded (1)","warnings": [],"checkedAt": "2026-09-05T19:12:05.158Z","schemaVersion": "1.0","workbookId": "e460d0abb319dc6efbfc47b1503256dd9514474dcd9d5d3c0555e1899ba7deb6","sha256": "e460d0abb319dc6efbfc47b1503256dd9514474dcd9d5d3c0555e1899ba7deb6","sheets": [],"dateSystem": null,"cellCount": 0,"formulaWarnings": [],"syntheticFixture": true,"redirectChain": []}
Example D — 1904 date system, paid; the calendar date is retained. Run DzXstlMxbR4e5avgp.
{"input": "https://api.apify.com/v2/key-value-stores/b0cgFsJRqVv3XOZyG/records/xlsx-1904.xlsx","sourceUrl": "https://api.apify.com/v2/key-value-stores/b0cgFsJRqVv3XOZyG/records/xlsx-1904.xlsx","found": true,"status": "ok","resultCount": 1,"partial": false,"error": "","warnings": [],"checkedAt": "2026-09-05T19:12:10.745Z","schemaVersion": "1.0","workbookId": "a4eb2b684d90454faadb66abb7c9e77580ce7752fea358e9185f201783a4b9e6","sha256": "a4eb2b684d90454faadb66abb7c9e77580ce7752fea358e9185f201783a4b9e6","sheets": [{"name": "Dates1904","headers": ["label","date"],"rows": [{"label": "WAVE-A 1904 DATE","date": {"type": "date","value": "2026-09-01T00:00:00.000Z"}}],"rowNumbers": [2],"mergedRanges": []}],"dateSystem": "1904","cellCount": 4,"formulaWarnings": [],"syntheticFixture": true,"redirectChain": [],"expandedBytes": 15690,"zipEntries": 10}
R7. Field dictionary
input
string: requested normalized file URL, preserved even after redirects. Keep it with the task input; it is not necessarily the final download address.
sourceUrl
string: final public response URL used by the parser, or requested URL when no response was available. Treat query strings as potentially sensitive provenance.
found
boolean: true only for one complete useful paid unit. A row can exist with found:false because free explanations also use the dataset.
status
string: domain outcome listed below. Consumer routing should check status together with found, partial and error.
resultCount
integer: one for a complete useful unit, zero for a free notice. It is not the number of pages, words, sheets or cells nested in that unit.
partial
boolean: this row describes an incomplete observation or a limit. The run can still be partial while a particular completed row is not.
error
string: empty on useful completion and clean absence; nonempty on access, transport, format, resource or parsing failure. Do not erase it during export.
warnings
array of strings: bounded explanatory limitations or source details. A warning does not by itself imply a failed or billable record; inspect the documented outcome.
checkedAt
ISO8601 UTC string: time the actor produced this observation, not source creation/publication time or a certification of freshness.
schemaVersion
string: currently1.0. Use it when validating downstream shapes and retain the actor build identifier alongside your export.
syntheticFixture
boolean: whether the supplied source belongs to our named hosted fixture prefix. An arbitrary customer document is not synthetic simply because it contains the same marker.
workbookId and sha256
The lowercase64-character SHA256 of the actual downloaded XLSX bytes, available after initial signature and MIME validation. It identifies the source container, not a recalculated model or an exported CSV. The internal normalized ZIP never replaces this provenance hash. Visually identical books can have different hashes because ZIP timestamps, workbook metadata or the producer changed.
sheets
An array in source workbook order containing name, headers, rows, rowNumbers and mergedRanges. sheetNames selects which sheets appear; omitted sheets still participate in source resource checks. name is the original worksheet name. The actor does not infer a semantic table title or substitute a translated name.
headers is the stable output key list in physical column order through the last nonempty used column at or after headerRow. A blank heading becomes column_N, where N is the physical one-based column. Collisions receive sequential suffixes such as dup_2 and dup_3. Existing names take their position in the same left-to-right uniqueness procedure, so a naturally named column_6 can also acquire a suffix if that key was already generated.
rows contains plain JSON objects keyed by those headers. Missing positions use null, not an empty string, zero or a copied merged-cell value. Rows before the selected header row do not appear. Completely empty physical rows are not synthesized. rowNumbers is a parallel array of the actual one-based worksheet row positions, so rows[index] and rowNumbers[index] refer to the same source row.
mergedRanges contains ranges such as H2:I2. Only stored top-left content is preserved; merged children are not automatically filled from the parent. A null merged child is therefore different from a repeated category value. If your application needs fill-down behavior, apply it explicitly after conversion and preserve a distinction between source values and inferred fill values.
Ordinary cells and dates
String, number, boolean and null are native JSON values. Rich text is flattened to its text content without font formatting. An ordinary error cell is tagged as {type:"error",value:"#DIV/0!"} or the source error string. A literal string beginning with an equals sign remains a string, rather than becoming a formula instruction.
A recognized date is {type:"date",value:"2026-09-01T00:00:00.000Z"}. Its value is an ISO8601 representation derived from the workbook serial and date system, not a timezone copied from the user's locale. An unformatted numeric serial remains a number. A date-looking text cell remains text. Consumers should use the tag rather than trying to recognize every date from string spelling.
Excel's1900 date system contains a fictitious leap day at serial60. This converter preserves that case as type:date,value:null,serial:60,dateSystem:"1900" with a warning. It does not silently substitute a real calendar day. Ordinary pre-March1900 serials and the1904 system use the appropriate epoch; the fixture verifies that the same modern calendar date survives the1904 offset.
Formula cells
A formula is an object with type:"formula", formula, cachedValue and cachedType. The expression is source data. cachedType distinguishes number, string, boolean, date, error and missing. cachedValue can itself be a tagged date or error object. A missing cache is null with cachedType:"missing" and an explicit formulaWarnings entry; it is not zero and does not cause evaluation.
Shared/array metadata can additionally include formulaType, sharedIndex or range when present in the source. A shared expression absent from that cell remains formula:null with a warning. The actor does not expand relative references or promise the textual expression that Excel would display after resolving a shared formula. Cached values can still be reported when the source supplies them.
dateSystem, cellCount and formulaWarnings
dateSystem is the string1900 or1904 from the workbook properties. cellCount counts nonempty stored cells across the whole source, including header/preamble cells, formulas and unselected sheets. It is not just the number of cells in the output rows and is not a billing unit. formulaWarnings contains located notices about missing caches, unresolved shared expressions or exceptional date interpretation; no formula is recalculated in response to a warning.
expandedBytes, zipEntries and redirectChain
expandedBytes counts the validated uncompressed ZIP entry bytes; zipEntries counts original central-directory entries, including directories. These counters describe source processing, not the size of the nested JSON. redirectChain records file-download redirects. None of these counters adds another paid workbook event.
R8. Evidence and boundaries
The exact parser dependency is ExcelJS4.4.0 using stream.xlsx.WorkbookReader. Workbook relationships, styles and shared strings are ordered before sheets in a bounded scratch ZIP so source archive order cannot silently change date interpretation. The guard uses yauzl3.2.0 and yazl3.3.1 with streaming XML validation through saxes6.0.0.
The installed ExcelJS streaming source converts some formula caches through numeric parsing regardless of their original boolean/error type. This build preserves those original cache types from validated worksheet XML and reconciles them with streamed rows. That is type preservation, not formula evaluation. Tests use actual generated workbooks containing cached booleans, errors and strings as well as the default numeric cache.
R9. Decision routing
Route a row to your useful-results branch only when found is true, resultCount is one and error is empty. Apply the domain completeness rules below before merging its nested data into a canonical table or search index. Preserve provenance at the destination. A consumer should be able to trace a single derived text fragment or cell back to its input file, page or sheet and the run that produced it.
Route a clean absence to an observation log. It means no useful content was produced within this actor's supported operation on those bytes. It does not mean a business entity is absent, a file is legally empty, or a customer has no data. Do not replace a previous successful document with empty data solely because a later URL returned a notice; compare the byte identity, source status and run completeness first.
Route a source or parser error to a retry or review queue with the original reason. A temporary network outage can justify a bounded later retry, whereas a password requirement, unsupported format or hard size limit needs a changed input or a different supported workflow. Retrying identical unsupported bytes every minute adds work without addressing the refusal. Keep the last good result until a verified replacement is available.
Route partial runs using OUTPUT.unprocessed and the domain counters. A cap can leave an input unprocessed, or a parser can reject the whole oversized unit after inspecting it. These are different from a complete negative. Split a large batch at the input-file boundary, preserving the input list and already delivered identities. Do not blindly rerun the entire batch unless repeated delivery and possible repeated billing are acceptable.
Route a fatal budget, pricing, storage or charge error to an operator. Those failures concern delivery integrity rather than the contents of a source document. Reconcile billed event counts and dataset contents before resuming. A workflow that checks only the process status will miss uncertain writes; a workflow that checks only dataset length will miss pricing failures or incomplete batches.
For status=ok, inspect sheet names, header keys and rowNumbers before a mapping step. Treat formula.cachedValue as a source-saved value whose freshness must be established by the producing system. If a required field has a missing cache, route that record to review or request a recalculated authorized export; do not silently use zero.
For status=not_found, the selected output has no content under the chosen header configuration. A fully empty workbook is a clean negative. A header-only selection with actual headings is useful schema content and can be a complete result even with no data rows. Document this distinction when your importer requires at least one transaction row.
For limit_exceeded, do not import sheets from the notice: incomplete books deliberately have no paid nested output. A low maxCells is a validation threshold, not a request for a row prefix. Selecting a smaller sheet does not bypass the whole-source cap. Request a smaller authorized source workbook or prepare distinct complete workbooks upstream.
R10. Commercial playbooks
Playbook1: controlled reporting import. An approved system exports a workbook to a direct download URL. Your workflow calls the actor with exact sheet names and headerRow, validates the typed result and inserts rows into a staging table with workbookId,sheetName and physical row number. A final mapping step converts the producer's column names into your destination schema and rejects missing required formula caches.
Playbook2: spreadsheet migration review. Convert a representative original book containing the actual date system, merges and formulas. Review generated headers and null merged children with the data owner. Freeze the accepted mapping, then process small batches using the same actor build. Keep workbook hashes so a revised source is reviewed as a new revision instead of accidentally merged into the old import.
R11. Integration recipes
Use the actor through the normal Apify API or SDK. Supply the same JSON input you tested in the Console, set a suitable timeout and memory allocation, and use a maximum total charge limit appropriate for the unit price. Store your API token in your workflow's credential store or environment, not in shared source files, URLs inside documents or copied README examples. Consult the official Apify run API for the current request and authentication details.
An asynchronous integration starts a run, stores its ID and waits for a terminal result before reading the dataset. A platform webhook can notify an existing endpoint that a run finished; the webhook payload is an event, not the converted document. Retrieve the default dataset and OUTPUT summary for the specific run identified in that event. Verify the run ID and deduplicate webhook delivery because webhook redelivery should not repeat your downstream insertion.
In n8n, a practical sequence is a scheduled trigger or authorized file-list source, an Apify run step, a wait/poll step, dataset retrieval and a conditional branch on found/status/error. Follow that with a staging table or document store. Use the run ID as the workflow correlation key. Keep the token in n8n credentials and avoid logging the entire signed source URL when your workflow distributes logs beyond the people who can access the file.
Treat one dataset record as the parent record. When you flatten its nested arrays into child tables, copy the file identity, sourceUrl, checkedAt and relevant page/sheet/row coordinates into every child. Store a child identifier that is stable within that conversion. Flattening for analysis does not create extra actor result events, and counting flattened rows is not a way to calculate the actor invoice.
JSON is the authoritative export for nested and typed results. CSV exports can serialize arrays into a cell and spreadsheet tools can reinterpret leading zeros, date-like strings or long numbers. If a downstream tool needs a flat CSV, build it from a validated JSON result with explicit column types and escaping. Keep the original JSON next to the derived file so a reviewer can distinguish actor output from export-time coercion.
Before an automated merge, validate both shape and outcome. Reject records with nonempty error from the success branch, inspect warnings according to your quality policy and verify required domain fields. Commit the merge only after the unit's completeness requirements pass. If a later run fails, record that attempt separately and preserve the previous successful content rather than interpreting the failure as a deletion.
For large result exports, use the platform's normal dataset pagination and store each page under the same run identifier. Page retrieval is a read of an already created dataset, not a new conversion run. Starting another actor run to recover an export download can cause repeated conversion and billing. Retry the export operation against the existing dataset when the actor run itself was already complete.
Separate transport retries from business retries. The actor already performs a bounded retry for eligible source failures. Your orchestrator can perform a later retry when the source is expected to recover, but it should record why that retry was scheduled and which inputs were not delivered. Never let both layers recursively retry an entire batch without a total attempt limit and an explicit treatment of already delivered units.
For a relational destination, retain a parent workbooks record, a worksheet record per sheet and a row record with workbookId,sheetName,rowNumber. Use a mapping table for normalized header keys when the source can change. Object key order is convenient for inspection but should not be the only link between a destination column and the workbook's physical column.
When exporting formulas for review, store formula and cachedValue in separate destination fields rather than replacing the whole formula object with a string. Likewise, keep the date type tag or a typed destination date column. A spreadsheet application opening CSV may evaluate formula-looking strings or reinterpret numbers; escape and type the derived export according to the receiving tool's rules.
R12. Operating guide
Files are processed sequentially to keep peak memory and request pressure bounded. The actor does not launch a separate browser per file, enqueue an unbounded crawl or parallelize all supplied documents. More input URLs can increase total work and the chance of reaching the240-second work deadline; it does not create unlimited processing time. The platform run timeout is300 seconds, leaving time to record a summary and close the SDK.
Source requests have their own bounded timeout and at most two retries, only for eligible network failures,429 and server errors. Backoff is at least one second and then three seconds; Retry-After is respected when it fits within the remaining deadline. Empty success responses, unsupported bytes and normal4xx format/access failures are not repaired by repeated downloading. A deadline-limited retry leaves an explicit error instead of silently substituting fixture data.
There is no cross-run cache that can be assumed to suppress a result event. Deduplicate your file list before scheduling if repeated conversion is unnecessary. Use source revision identifiers or your own prior hashes where you already possess the file bytes. Be careful with expiring links: two different signed URLs may refer to the same file, while one stable URL may return a new revision. The actor cannot infer your business retention or replay policy from URL spelling alone.
Monitor the OUTPUT counters and free notices alongside charged event counts. A rising limit rate can mean your documents changed shape or size. A rising source-error rate can mean access restrictions, expired links, robots changes or an outage. A drop in useful outputs with stable HTTP success can mean unsupported content rather than a network failure. Inspect a representative affected file and change one cause at a time.
Before upgrading the actor build used by a schedule, replay your approved regression inputs against the new build under a small budget. Compare source hashes, domain fields, useful-unit counts and exact negative semantics. Keep the previous output export and build identifier so a changed reading order, date representation or OCR word segmentation is distinguishable from an upstream content change.
Run logs and datasets can contain source URLs and extracted content. Choose access permissions and retention periods appropriate for those materials. Temporary parser files are implementation scratch space, not a backup of the source archive. Keep source originals in your own authorized storage if you need them for a later audit. Deleting a local temporary file does not delete an already exported dataset or a downstream copy.
A complete local test suite verifies defined boundaries, but ongoing production monitoring is still necessary. Recheck the default source, MIME and SHA after fixture hosting changes. Recheck container dependencies and resource usage after a build change. Platform memory or engine changes can affect startup cost even if the same marker still appears in output; cost conclusions need measured platform runs, not a developer-laptop timing.
A high compression ratio is not itself a promise of safety. The actor verifies expanded bytes and actual XML structure before ExcelJS materializes rows. A small download can therefore produce a free expansion refusal. Preserve that reason in monitoring instead of retrying the archive as if the network download had failed.
The zero-start price makes an explicit zero result budget meaningful. The local build contains a guard for the SDK3.7.2 behavior that converts a configured zero cap into Infinity. The converter checks the original configured zero before using SDK budget headroom, and its actual SDK test verifies zero paid results at that boundary. An absent cap remains the normal uncapped case.
R13. FAQ
Where should I report a reproducible issue? Use the actor's Store Issues channel after publication, with the run ID, actor build, relevant input limits, status/error and a minimal file you have permission to share. Do not post passwords, API tokens, confidential extracted text or active signed URLs in a public issue. If the document cannot be shared, provide a sanitized original fixture that reproduces the same parser behavior.
Does a public URL prove authorization? No. You are responsible for ownership, permission and downstream use. A robots allow rule concerns crawler access, while copyright, confidentiality and source terms concern other obligations. This product does not grant a license to redistribute an archive or access content behind a login. It processes the public file routes you supply under the documented network and format restrictions.
Why did I receive a free row instead of useful text or cells? Read status and error together. Clean absence has an empty error. A resource, format or transport refusal has a reason. The notice exists so your workflow can distinguish an empty supported input from an unsuccessful attempt. Removing that distinction would make failed imports look like intentional empty data.
Can I increase the limit beyond the form maximum? No. Runtime validation enforces the same hard caps even when input is sent directly through the API. Split documents at an authorized preparation step, reduce the batch or choose a product with a larger documented contract. A larger monetary cap does not disable byte, page, cell, pixel or deadline limits.
Will a repeat run be free because the URL is unchanged? No. This actor has no persistent cross-run replay ledger. Repeating a successful conversion can create another result event even if the URL or file hash is unchanged. Reuse an existing dataset for another export, or implement deduplication in your own workflow if your use case needs it.
Is confidence or a successful parse a guarantee of correctness? No. Structured output means the engine completed the documented operation on the received bytes. It does not certify the source statement, file author's intent, financial totals, legal interpretation or downstream business decision. Apply your domain's review requirements before making consequential decisions from extracted content.
Is this page a guarantee of platform cost or availability? No. The prices above were read back from the deployed tariff on 2026-09-05 and the examples come from accepted platform runs of the same build; check the tariff shown on the Store page before a large run, because a tariff change is an operator action, not something inferred from this text.
Will formulas be refreshed? No. The expression and any cached value are returned distinctly. A formula without a cache remains missing with a warning. External references are not fetched and macros never run.
Does maxCells select the first N cells? No. It limits the entire source workbook, including cells outside selected sheets. Overflow refuses the whole book for free. This prevents a partial book from being presented as a complete import.
Why did an empty heading become column_6? JSON row keys must be stable and unique. The generated name retains the physical column number. Duplicate names get suffixes in source column order, and the headers array documents the exact mapping used by that result.
Why are merged children null? The source stores the top-left value and the merge range. Filling child cells would add inferred values and could duplicate totals. mergedRanges lets an authorized downstream transformation make that decision explicitly.
Does it preserve Excel precision and formatting? Numeric cells are JSON numbers based on the stored spreadsheet value. Display formatting, locale-specific separators, leading zeros expressed only by formatting and arbitrary precision beyond the source numeric representation are not recreated. True string identifiers retain their string type.
R14. Sources, rights and support
Process only documents and images you own or are authorized to transform. Retain applicable notices, attribution and confidentiality restrictions in derived data. Conversion into JSON does not remove copyright or make private information public. Avoid redistributing a source archive just because the input was technically accessible through a public download link.
The original Wave A fixtures are generated for testing and include fixed control phrases rather than customer material. Their syntheticFixture flag identifies that origin in hosted examples. Production URLs, parser outputs and source content are treated as data, never as instructions to execute code or request unrelated resources.
The actor uses the platform's existing dataset, key-value store, API, schedule and webhook capabilities. It does not contact people, submit forms, bypass a login, create external documents or modify the input source. Those actions, if required by a customer workflow, remain separate authorized steps owned by that workflow.
Primary parser reference: ExcelJS workbook and streaming reader documentation. This build pins ExcelJS4.4.0 and inspects its installed streaming/date utilities. ZIP handling uses the yauzl reader and yazl writer; XML is parsed without DTD or external-entity resolution.
The fixture workbooks contain original Wave A values. Fixed document and ZIP timestamps make repeated fixture generation byte-identical. Claude will upload the three files and compare each binary record directly with MANIFEST.sha256 before platform acceptance. No externally downloaded financial sample is used as the default or as a claim of permission.
Related-tool links below point only to published actors of the same author. The output examples above are accepted platform rows, not local fixture output.
Related tools
Related tools for adjacent workflows in data pipelines for AI applications.
| Actor | What it does |
|---|---|
| Structured Data Extractor | Pair it in the data pipelines for AI applications workflow: Extract title, meta, JSON-LD, headings, links, emails, and price observations from up to 100 authorized... |
| URL to Markdown Converter | Pair it in the data pipelines for AI applications workflow: Convert up to 100 authorized public HTML pages into clean Markdown for RAG, AI agents, SEO research, and... |
| Live Price Oracle | Pair it in the data pipelines for AI applications workflow: Get timestamped DexScreener market observations for up to 100 token contracts or bounded ticker searches |
| RAG Dataset Builder | Pair it in the data pipelines for AI applications workflow: Turn buyer-authorized public website sitemaps into bounded, source-linked text chunks for RAG, search,... |