leadtext
leadtext
leadtext
Invoices, receipts, statements
Auto-title papers
Matter-ready naming
Field, onboarding, reporting ops
Shot logs, call sheets, deliverables
Configs, audit logs, incidents
Transcripts, lesson plans, records
Invoices, product sheets, shipping
Leases, inspections, work orders
Receipts, reports, reimbursements
BOLs, PODs, carrier invoices
Official SDK
Python
Full type hints and async/await support. Works with Python 3.8+ and integrates smoothly with your existing Python workflows.
Rename PDFs, split multi-page documents, and extract structured data using the official Python SDK for Renamed.to.
- 1Install with pip install renamed and initialize with your API key
- 2Call rename(), pdf_split(), or extract() with PDF bytes or file path
- 3Use sync or async client for AI-generated filenames, split documents, or structured JSON
On this page
Installation
pip install renamedpoetry add renamedpipenv install renameduv pip install renamedQuickstart
Initialize the client and start making API calls.
import osfrom renamed import RenamedClient# Initialize the clientclient = RenamedClient(api_key=os.environ["RENAMED_API_KEY"])# Rename a PDFwith open("invoice.pdf", "rb") as f: result = client.rename(f.read())print(result.suggested_filename)# -> "2024-01-15_AcmeCorp_INV-1234.pdf"# Split a multi-page PDFwith open("documents.pdf", "rb") as f: job = client.pdf_split(f.read(), mode="smart")print(job.documents)# -> [{"filename": "...", "download_url": "..."}, ...]# Extract structured datawith open("receipt.pdf", "rb") as f: data = client.extract(f.read())print(data)# -> {"vendor": "...", "date": "...", "amount": "..."}Rename a PDF
Pass PDF bytes or a file path to get an AI-generated filename. Use custom instructions to control the naming format.
import osfrom pathlib import Pathfrom renamed import RenamedClientclient = RenamedClient(api_key=os.environ["RENAMED_API_KEY"])# Rename from a local filepdf_path = Path("./documents/invoice.pdf")result = client.rename(pdf_path.read_bytes())print(result)# RenameResult(# suggested_filename="2024-01-15_AcmeCorp_INV-1234.pdf",# confidence=0.95,# metadata={"vendor": "Acme Corp", "date": "2024-01-15", "type": "invoice"}# )# Use custom naming instructionscustom_result = client.rename( pdf_path.read_bytes(), instructions="Format: YYYY-MM-DD_VendorName_Amount")print(custom_result.suggested_filename)# -> "2024-01-15_AcmeCorp_$1250.pdf"# Async version with AsyncRenamedClientimport asynciofrom renamed import AsyncRenamedClientasync def rename_async(): async_client = AsyncRenamedClient(api_key=os.environ["RENAMED_API_KEY"]) result = await async_client.rename(pdf_path.read_bytes()) return result.suggested_filename# asyncio.run(rename_async())Split a PDF
Split multi-page PDFs into separate documents. The API uses async jobs for large files—poll for completion or use the built-in wait helper.
import osfrom pathlib import Pathfrom renamed import RenamedClientclient = RenamedClient(api_key=os.environ["RENAMED_API_KEY"])pdf_bytes = Path("./documents/combined.pdf").read_bytes()# Smart split: AI detects document boundariesjob = client.pdf_split(pdf_bytes, mode="smart")# Option 1: Wait for completion (built-in polling)completed = job.wait_for_completion()print(completed.documents)# [# SplitDocument(filename="invoice_1.pdf", pages=[1, 2], download_url="..."),# SplitDocument(filename="invoice_2.pdf", pages=[3, 4], download_url="..."),# ]# Option 2: Manual polling for progress updatesimport timestatus = client.get_job(job.job_id)while status.state == "processing": print(f"Progress: {status.progress}%") time.sleep(1) status = client.get_job(job.job_id)# Download split documentsoutput_dir = Path("./output")output_dir.mkdir(exist_ok=True)for doc in completed.documents: pdf_data = client.download_file(doc.download_url) (output_dir / doc.filename).write_bytes(pdf_data) print(f"Saved: {doc.filename}")# Async version with AsyncRenamedClientimport asynciofrom renamed import AsyncRenamedClientasync def split_async(): async_client = AsyncRenamedClient(api_key=os.environ["RENAMED_API_KEY"]) job = await async_client.pdf_split(pdf_bytes, mode="smart") completed = await job.wait_for_completion() return completed.documents# asyncio.run(split_async())Extract Data
Extract structured data from invoices, receipts, and other documents. Use Pydantic models for type-safe extraction.
import osfrom pathlib import Pathfrom renamed import RenamedClientclient = RenamedClient(api_key=os.environ["RENAMED_API_KEY"])# Basic extraction (returns inferred fields as dict)pdf_bytes = Path("./documents/receipt.pdf").read_bytes()data = client.extract(pdf_bytes)print(data)# {"vendor": "Coffee Shop", "date": "2024-01-15", "total": "$4.50", ...}# Typed extraction with Pydantic modelfrom pydantic import BaseModelclass LineItem(BaseModel): description: str quantity: int unit_price: floatclass Invoice(BaseModel): invoice_number: str vendor: str date: str line_items: list[LineItem] subtotal: float tax: float total: floatinvoice = client.extract(pdf_bytes, schema=Invoice)# invoice is fully typed as Invoiceprint(f"Invoice #{invoice.invoice_number}")print(f"Vendor: {invoice.vendor}")print(f"Total: ${invoice.total:.2f}")for item in invoice.line_items: print(f" - {item.description}: {item.quantity} x ${item.unit_price:.2f}")# Output:# Invoice #INV-2024-1234# Vendor: Acme Corp# Total: $1,337.50# - Widget Pro: 5 x $199.00# - Support Plan: 1 x $342.50Framework Integrations
Common integration patterns for popular frameworks.
FastAPI Endpoint
Use the async client in FastAPI for high-performance file uploads with automatic validation.
# main.pyimport osfrom fastapi import FastAPI, UploadFile, HTTPExceptionfrom pydantic import BaseModelfrom renamed import AsyncRenamedClientapp = FastAPI()# Initialize the async client at startupclient = AsyncRenamedClient(api_key=os.environ["RENAMED_API_KEY"])class RenameResponse(BaseModel): suggested_filename: str confidence: float@app.post("/api/rename", response_model=RenameResponse)async def rename_pdf(file: UploadFile): if not file.filename or not file.filename.endswith(".pdf"): raise HTTPException(status_code=400, detail="File must be a PDF") pdf_bytes = await file.read() result = await client.rename(pdf_bytes) return RenameResponse( suggested_filename=result.suggested_filename, confidence=result.confidence, )@app.post("/api/split")async def split_pdf(file: UploadFile, mode: str = "smart"): pdf_bytes = await file.read() job = await client.pdf_split(pdf_bytes, mode=mode) completed = await job.wait_for_completion() return { "job_id": completed.job_id, "documents": [ {"filename": doc.filename, "pages": doc.pages} for doc in completed.documents ], }Flask Route
Integrate with Flask using the sync client for traditional web applications.
# app.pyimport osfrom flask import Flask, request, jsonifyfrom werkzeug.utils import secure_filenamefrom renamed import RenamedClient, RenamedErrorapp = Flask(__name__)app.config["MAX_CONTENT_LENGTH"] = 16 * 1024 * 1024 # 16MB maxclient = RenamedClient(api_key=os.environ["RENAMED_API_KEY"])@app.route("/api/rename", methods=["POST"])def rename_pdf(): if "file" not in request.files: return jsonify({"error": "No file provided"}), 400 file = request.files["file"] if not file.filename or not file.filename.endswith(".pdf"): return jsonify({"error": "File must be a PDF"}), 400 try: pdf_bytes = file.read() result = client.rename(pdf_bytes) return jsonify({ "suggested_filename": result.suggested_filename, "confidence": result.confidence, }) except RenamedError as e: return jsonify({"error": str(e)}), 500@app.route("/api/extract", methods=["POST"])def extract_data(): if "file" not in request.files: return jsonify({"error": "No file provided"}), 400 file = request.files["file"] pdf_bytes = file.read() try: data = client.extract(pdf_bytes) return jsonify(data) except RenamedError as e: return jsonify({"error": str(e)}), 500if __name__ == "__main__": app.run(debug=True)Error Handling
The SDK raises typed exceptions that you can catch and handle appropriately.
from renamed import RenamedClient, RenamedError, RateLimitErrorclient = RenamedClient(api_key="...")try: result = client.rename(pdf_bytes)except RateLimitError as e: print(f"Rate limited. Retry after {e.retry_after} seconds")except RenamedError as e: print(f"API Error: {e.code} - {e.message}")Full documentation on GitHub
For more examples, advanced usage patterns, and detailed API documentation, see the full Python SDK README on GitHub.
Read the Python SDK docsFrequently asked questions
- What Python versions are supported?
- The Python SDK supports Python 3.8 and above. It includes type hints for IDE autocompletion and static analysis.
- Does the SDK support async/await?
- Yes, the SDK provides both sync and async interfaces. Use the async client for better performance in asyncio applications.
- How do I install extra dependencies?
- The base package includes all required dependencies. No extras are needed for standard usage.