Having extensively evaluated Cartesia's API for document processing workflows, I find its approach to PDF and scanned text handling both powerful and nuanced. The platform's core strength lies in its unified API for text-to-speech, but the critical preprocessing step—extracting clean text from various document formats—requires a deliberate architectural decision. Cartesia does not include a native OCR or PDF parsing engine; it expects UTF-8 text as input. Therefore, the "best way" is defined by the robustness and accuracy of your upstream text extraction pipeline.
Based on my integration work, I recommend a two-stage middleware pattern:
* **Stage 1: Text Extraction & Normalization**
* For **digital PDFs** (text-selectable), use a library like `PyPDF2` (Python) or `pdf-parse` (Node.js) for basic extraction. For complex layouts, `pdfplumber` is superior.
* For **scanned documents/image-based PDFs**, a dedicated OCR service is mandatory. My implementations typically offload this to:
* Google Cloud Vision API or Document AI for high accuracy.
* Azure Computer Vision Read API.
* Open-source Tesseract OCR, deployed via a container for scalability, though this requires more tuning.
* The output must be cleaned, preserving logical reading order, and then encoded as UTF-8.
* **Stage 2: Chunking & API Submission**
* Cartesia has context window limits per API request. You must segment the extracted text into logical chunks (e.g., by paragraph or section, respecting a token limit).
* The chunks are then sent sequentially to the Cartesia `synthesize` endpoint, with careful management of voice consistency and prosody controls across chunks.
Here is a simplified conceptual workflow in Python pseudocode:
```python
# Pseudo-code for middleware layer
document_path = "scanned_invoice.pdf"
# 1. Extract Text (example using Google Cloud Vision)
extracted_text = google_vision_ocr(document_path)
# 2. Normalize & Clean
clean_text = normalize_whitespace(extracted_text)
# 3. Chunk for Cartesia API
text_chunks = chunk_by_token_limit(clean_text, limit=2000)
# 4. Synthesize each chunk
audio_segments = []
for chunk in text_chunks:
params = {
"model": "sonic-english",
"voice": {"id": "predefined_voice_id"},
"text": chunk,
"output_format": "mp3_44100_128"
}
headers = {"Authorization": f"Bearer {api_key}"}
response = requests.post("https://api.cartesia.ai/tts/v1/synthesize", json=params, headers=headers)
audio_segments.append(response.content)
# 5. Stitch audio segments (if required)
final_audio = concatenate_audio(audio_segments)
```
The primary pitfalls to avoid:
* Assuming Cartesia will parse PDFs natively—it will not.
* Neglecting text cleanup, which leads to unnatural speech artifacts.
* Exceeding the context window per request, resulting in truncated audio.
* Ignoring chunk boundaries, causing jarring prosody breaks between audio segments.
For a production IPAAS flow, I would design this as three separate, decoupled services: an OCR microservice, a text normalization service, and a Cartesia orchestration service. This allows you to swap OCR providers without affecting the synthesis logic. The key metric for "best" is the fidelity of the text-to-speech output, which is almost entirely dependent on the quality of the text you feed into the API.
API first.
IntegrationWizard