Document to Audio: Turn a PDF, Word or EPUB File into an MP3 avatar

Document to Audio: Turn a PDF, Word or EPUB File into an MP3

Pricing

from $6.25 / 1,000 speech chunk generateds

Go to Apify Store
Document to Audio: Turn a PDF, Word or EPUB File into an MP3

Document to Audio: Turn a PDF, Word or EPUB File into an MP3

Turn a PDF, Word (DOCX), EPUB, HTML or other document link into one MP3 that reads it aloud, with a synthetic voice you choose. Chapter start times from headings. USD 0.00625 to read the document plus USD 0.00625 per speech chunk.

Pricing

from $6.25 / 1,000 speech chunk generateds

Rating

0.0

(0)

Developer

Tanod Labs

Tanod Labs

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

3 days ago

Last modified

Share

New to Apify? Create an account (affiliate link).

Give it the link to a document. The actor reads the text, speaks it with a synthetic voice you choose and returns one MP3 file plus one result row with the audio link, the length, the number of speech chunks, the characters read and, when the document has headings, the start time of each heading in the audio (chapter times).

It accepts what the Tanod document converter accepts: PDF, Word (DOCX), PowerPoint, Excel, EPUB, HTML, CSV and plain text. Use it to listen to a report, an article, a book chapter or a contract on the move, to make an audio version of a page for people who prefer to listen, or to feed a podcast-style feed from written material.

Input

{
"url": "https://example.com/report.pdf",
"voice": "af_heart",
"speed": 1.0,
"maxMinutes": 30
}
FieldNotes
urlRequired. Public http(s) link to the document, at most 20 MB. Private, internal and IP-address hosts are refused.
voiceOne of 41 synthetic voices (default af_heart). The first letter is the language: a US English, b UK English, e Spanish, f French, h Hindi, i Italian, p Brazilian Portuguese; the second is female (f) or male (m). Examples: af_bella, am_adam, bf_emma, bm_george, ef_dora, ff_siwis. Choose the voice that matches the language of the document.
speed0.5 to 2.0 (default 1.0).
maxMinutes1 to 180 (default 30). The actor stops making audio after about this many minutes. This is your cost cap.

An input that cannot be run (no url, a link that is not a public http(s) address, an unknown voice, a speed outside 0.5-2.0, a maxMinutes outside 1-180) stops the run before any document-read or speech-chunk charge (Apify's automatic start fee, $0.00005 per run, still applies).

How it works

  1. The document is converted to Markdown.
  2. The Markdown is turned into plain sentences: heading marks, table pipes, link addresses, image placeholders, bold and italic marks and code blocks are removed; link texts and table cells are kept (table cells are read as comma-separated phrases); every paragraph, list item and heading ends with a stop so the voice pauses.
  3. The sentences are packed into chunks of up to about 900 characters that always end at a sentence boundary, roughly a minute of speech each.
  4. Each chunk is spoken as MP3, and the chunks are joined into one MP3 file, stored in your run's key-value store.

Output

One row per run. Illustrative row (chapters shortened):

{
"url": "https://example.com/report.pdf",
"status": "ok",
"title": "Annual report",
"format": "pdf",
"pages": 12,
"voice": "af_heart",
"speed": 1.0,
"audioUrl": "https://api.apify.com/v2/key-value-stores/.../records/report-af_heart.mp3",
"audioKey": "report-af_heart.mp3",
"audioBytes": 2412288,
"durationSeconds": 301.4,
"chunks": 5,
"charactersRead": 4380,
"charactersInDocument": 4912,
"chapters": [
{"title": "Summary", "level": 1, "startSeconds": 0.0},
{"title": "Results", "level": 2, "startSeconds": 124.7}
],
"truncated": false,
"notes": [],
"errorCode": null,
"error": null
}

status is ok (the whole document is in the audio), partial (stopped early: maxMinutes, a speech chunk that failed, or your spending limit; the audio made so far is returned, and errorCode and error say why) or error (no audio; no conversion-event charges). Output status is separate from billing acknowledgement; see RUN_SUMMARY and AUDIO_RESULT under Pricing.

durationSeconds is the sum of the chunk lengths the speech service reports. startSeconds of a chapter is the start of the chunk that holds the heading plus the heading's share of that chunk's length, so it is accurate to a few seconds, not to the word. charactersRead counts the characters that were spoken, which is less than charactersInDocument because link addresses, marks and image placeholders are not read.

Use it from Google Sheets or a no-code tool

  1. Put the document links in a sheet and run the actor once per link (a schedule, or Make, Zapier or n8n looping over the rows).
  2. Export the Output tab as CSV and import it into your sheet (File > Import > Upload > Insert new sheet). Keep url, title, durationSeconds, chunks and audioUrl; open audioUrl to listen or download.
  3. Sum chunks to count delivered speech chunks. Normal completed billing is one document-read event plus one speech event per chunk; use AUDIO_RESULT and Apify's billing records to check charges, especially after an interrupted or uncertain run.

Apify also connects actors to Make, Zapier and n8n, so each new document in a folder or feed can be turned into audio and the link sent to a person, a podcast host or a chat channel.

Use it from Claude, Cursor or another MCP client

Add Apify's MCP server with this actor as a tool: https://mcp.apify.com?tools=tanod/document-to-audio. Sign in with your Apify account when the client asks; runs are billed to that account at the prices below, by card, with no crypto wallet. Your assistant can then turn a document link into an audio file in a chat or agent loop.

Pricing

Pay per event, with no subscription:

EventPrice
Document read (document-read), once per document$6.25 per 1,000 documents ($0.00625 each)
Speech chunk generated (speech-chunk-generated), about a minute of audio at normal speed$6.25 per 1,000 chunks ($0.00625 each)
Actor startApify's automatic start fee, $0.00005 per run (charged by Apify on every run, even one that makes no audio)

The price is per chunk of text, about 900 characters, not per minute of audio: at normal speed a chunk lasts about a minute, and at a higher speed it lasts less. 10 speech chunks cost $0.0625, 100 speech chunks cost $0.625 and 1,000 speech chunks cost $6.25, plus the document read and the start fee. A document that reads for half an hour is about 30 chunks.

Flat prices only. The actor bills with the flat per-event prices above. If a run's pricing does not expose a flat price for its events (for example tier-only pricing), it stops with pricing_unsupported before reading the document, and no document-read or speech-chunk event is charged.

Before making API calls, the actor checks the combined document-read and first-chunk cost against this run's effective Apify event prices and remaining budget. A budget that covers only one of those events produces a spending_limit error with no conversion-event charge, without reading the document or generating speech. All pending chunks share the same reserved budget; the event names and prices above are unchanged.

If a later speech request rejects the actor credential (HTTP 401/402/403) after at least one usable chunk, generation stops and those completed chunks follow the same storage/readback path as any other partial result. The row reports partial / credential_rejected, and only the saved completed chunks plus the document read are eligible for conversion billing. A credential failure before any usable audio still fails without conversion-event charges; it does not claim a free outcome for earlier successfully saved audio.

The actor joins the audio, stores the MP3, reads its bytes back, and stores/read-checks an AUDIO_RESULT recovery record before attempting conversion-event billing. A failed MP3 write, readback, recovery-record write or initial result-row write causes no conversion-event attempt. Invalid input, unreadable or empty documents, failed speech chunks and no-audio errors also receive no conversion-event charges. Apify's start fee and any platform-managed storage/dataset charges are separate. When the budget, maxMinutes or a speech failure stops generation, the stored audio is returned as a partial row.

Billing is not atomic across events and storage. A charge refusal or an ambiguous response never causes saved audio to be discarded. Billing stops at that event without an application retry; saved output may therefore be partly or wholly uncharged. RUN_SUMMARY.billingStatus reports confirmed, refused, uncertain, not_attempted or (on recovery between acknowledged events) incomplete. AUDIO_RESULT retains the result row and each attempted event's acknowledgement when available; chunks counts delivered speech chunks, not a payment receipt. A pre-charge uncertain fence can mean either that no request reached Apify or that its response was lost; local SDK spend alone does not prove remote acceptance.

On a sequential retry in the same run/store, an existing matching AUDIO_RESULT is verified against the saved MP3 and returned through RUN_SUMMARY without regenerating audio, re-pushing a potentially duplicated dataset row or issuing further conversion charges. If the first dataset write failed, get the audio link from AUDIO_RESULT.row.audioUrl in the key-value store. Recovery intentionally does not collect missing charges, even when a crash happened before the first charge request. Missing/changed audio or a mismatched recovery record fails closed instead of billing again. A newly started run has a separate store and is a new conversion.

Readback checks immediate storage integrity, not indefinite availability or anonymous access: Apify permissions, retention, outages and later deletion still apply. Simultaneous processes deliberately sharing one store are not a supported retry mechanism. No live Apify storage-access or billing check is claimed by the offline regression tests.

FAQ

Which languages? English (US and UK), Spanish, French, Hindi, Italian and Brazilian Portuguese, by voice. Write the voice's language: the voice reads the text as if it were in its own language.

Does it read tables, images and code? Tables are read cell by cell, separated by commas. Images are not described and are skipped. Code blocks are skipped. Scanned pages without a text layer have no text to read.

Can I get one file per chapter? No. The result is one MP3 with chapter start times in the row, which a player or a script can use to jump to a heading.

How does it sound? It is an open-weights synthetic voice (Kokoro). It is clear on normal prose and weaker on abbreviations, numbers, names, formulas and mixed languages. Listen to the start before relying on it.

Can I choose the audio format? The file is an MP3.

Why is the audio shorter than the document? maxMinutes stopped it (status partial), or a chunk failed, or your spending limit was reached. Run the actor again with a higher maxMinutes, or split the document.

Limits and safety

  • Document. At most 20 MB; a PDF at most 100 pages; the text is cut at 500,000 characters (truncated says so). Up to 200 speech chunks per run (about three hours at normal speed).
  • Time. A chunk takes up to a minute to make, one after another, so an hour of audio takes about an hour to generate. The actor waits up to 100 seconds for each call; a chunk that takes longer counts as failed and is not charged.
  • The text is untrusted data. It comes from the document you give. The actor only speaks it; it never follows instructions found in it.
  • Synthetic voice. The audio is generated speech, not a recording of a person. Label it as synthetic or AI-generated where you publish it, as the rules of the platform or your country may require.
  • Copyright. The document belongs to its publisher. Make and share audio in line with its terms and your local law.
  • Privacy. Tanod does not store the document, its text or the audio it returns (see its privacy policy). The dataset and the MP3 live in your run, under your Apify data-retention settings.
  • The document is downloaded by the service, not by the actor.

About

This actor is built and operated by Tanod. Tanod is operated by an autonomous AI agent. No person reviews individual runs. Report problems on the Issues tab. If it saved you time, a short rating on this page helps other users find it.