# Step 1: Create job and get presigned URL
RESPONSE=$(curl -s -X POST https://prod.visionapi.unsiloed.ai/v2/parse/upload \
-H "api-key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"file_name": "report.pdf",
"use_high_resolution": true,
"segmentation_method": "smart_layout_detection",
"ocr_mode": "auto_ocr",
"merge_tables": false
}')
JOB_ID=$(echo "$RESPONSE" | jq -r '.job_id')
UPLOAD_URL=$(echo "$RESPONSE" | jq -r '.upload_url')
# Step 2: Upload file
curl -X PUT "$UPLOAD_URL" \
-H "Content-Type: application/pdf" \
--data-binary @report.pdf
# Step 3: Poll for results
curl -X GET "https://prod.visionapi.unsiloed.ai/parse/$JOB_ID" \
-H "api-key: your-api-key"
{
"job_id": "a3f1c2d4-7e8b-4a9f-b2c1-123456789abc",
"upload_url": "https://upload.visionapi.unsiloed.ai/uploads/a3f1c2d4.../report.pdf?signature=...",
"expires_at": "2025-10-22T07:06:16Z",
"upload_method": "PUT",
"upload_headers": {
"Content-Type": "application/pdf"
}
}
Create a parse job and receive a presigned URL to upload your document directly — supports larger file sizes than the standard endpoint.
# Step 1: Create job and get presigned URL
RESPONSE=$(curl -s -X POST https://prod.visionapi.unsiloed.ai/v2/parse/upload \
-H "api-key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"file_name": "report.pdf",
"use_high_resolution": true,
"segmentation_method": "smart_layout_detection",
"ocr_mode": "auto_ocr",
"merge_tables": false
}')
JOB_ID=$(echo "$RESPONSE" | jq -r '.job_id')
UPLOAD_URL=$(echo "$RESPONSE" | jq -r '.upload_url')
# Step 2: Upload file
curl -X PUT "$UPLOAD_URL" \
-H "Content-Type: application/pdf" \
--data-binary @report.pdf
# Step 3: Poll for results
curl -X GET "https://prod.visionapi.unsiloed.ai/parse/$JOB_ID" \
-H "api-key: your-api-key"
{
"job_id": "a3f1c2d4-7e8b-4a9f-b2c1-123456789abc",
"upload_url": "https://upload.visionapi.unsiloed.ai/uploads/a3f1c2d4.../report.pdf?signature=...",
"expires_at": "2025-10-22T07:06:16Z",
"upload_method": "PUT",
"upload_headers": {
"Content-Type": "application/pdf"
}
}
/v2/parse/upload with your configuration — the API creates a parse job and returns a short-lived presigned URL.GET /parse/{job_id} to track progress and retrieve results — the same endpoint as v1.AwaitingUpload. It transitions to Queued once the upload completes, then to Processing, and finally Succeeded or Failed. See Get Parse Job Status for the full response schema and polling examples."report.pdf"). Determines the MIME type for the presigned URL. Supported formats: PDF, images (PNG, JPEG, TIFF), and office documents (DOCX, PPTX, XLSX).true.smart_layout_detection (default) detects fine-grained elements using bounding boxes. page_by_page treats each page as a single segment and is faster for simple documents.auto_ocr (default) applies OCR only where needed. force_ocr forces OCR on every text element — recommended for scanned documents.UnsiloedBeta (default) — handles rotated/warped text and irregular bounding boxes. UnsiloedHawk — higher accuracy for complex layouts and mixed content. UnsiloedStorm — enterprise-grade accuracy optimized for 50+ languages.false.false.false.false.false.false."1-5", "2,4,6", "[1,3,5]". Defaults to all pages.Unsiloed (default) or Other.["Table", "Formula"].validate_segments instead.Continue (default) skips failed pages and continues. Fail aborts the entire job on the first error.GET /parse/{job_id} to poll status and retrieve results.api-key header needed for the upload itself. Valid until expires_at.upload_url expires. Upload must complete before this time."PUT". Use an HTTP PUT request when uploading to upload_url.Content-Type set to the MIME type inferred from file_name./v2/parse/upload with your file name and configuration. The API returns a job_id and a short-lived presigned URL.
import requests
API_KEY = "your-api-key"
BASE_URL = "https://prod.visionapi.unsiloed.ai"
response = requests.post(
f"{BASE_URL}/v2/parse/upload",
headers={"api-key": API_KEY, "Content-Type": "application/json"},
json={
"file_name": "report.pdf",
"use_high_resolution": True,
"segmentation_method": "smart_layout_detection",
"ocr_mode": "auto_ocr",
"merge_tables": False,
},
)
response.raise_for_status()
data = response.json()
job_id = data["job_id"]
upload_url = data["upload_url"]
upload_headers = data["upload_headers"]
print(f"Job ID: {job_id}")
print(f"Upload URL expires: {data['expires_at']}")
{
"job_id": "a3f1c2d4-7e8b-4a9f-b2c1-123456789abc",
"upload_url": "https://upload.visionapi.unsiloed.ai/uploads/a3f1c2d4.../report.pdf?signature=...",
"expires_at": "2025-10-22T07:06:16Z",
"upload_method": "PUT",
"upload_headers": {
"Content-Type": "application/pdf"
}
}
upload_url and upload_headers from the response to PUT your file. No API key is needed for this request.
with open("report.pdf", "rb") as f:
put_response = requests.put(upload_url, headers=upload_headers, data=f)
put_response.raise_for_status()
print("Upload complete — job is now queued for processing")
upload_headers. A missing or mismatched Content-Type will cause the upload to be rejected with a 403.AwaitingUpload → Queued → Processing → Succeeded. Poll GET /parse/{job_id} using the same endpoint as v1.
import time
while True:
status_response = requests.get(
f"{BASE_URL}/parse/{job_id}",
headers={"api-key": API_KEY},
)
status_response.raise_for_status()
job = status_response.json()
print(f"Status: {job['status']}")
if job["status"] == "Succeeded":
print(f"Done! {job['total_chunks']} chunks extracted.")
break
elif job["status"] == "Failed":
raise RuntimeError(f"Job failed: {job.get('message')}")
time.sleep(5)
# Step 1: Create job and get presigned URL
RESPONSE=$(curl -s -X POST https://prod.visionapi.unsiloed.ai/v2/parse/upload \
-H "api-key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"file_name": "report.pdf",
"use_high_resolution": true,
"segmentation_method": "smart_layout_detection",
"ocr_mode": "auto_ocr",
"merge_tables": false
}')
JOB_ID=$(echo "$RESPONSE" | jq -r '.job_id')
UPLOAD_URL=$(echo "$RESPONSE" | jq -r '.upload_url')
# Step 2: Upload file
curl -X PUT "$UPLOAD_URL" \
-H "Content-Type: application/pdf" \
--data-binary @report.pdf
# Step 3: Poll for results
curl -X GET "https://prod.visionapi.unsiloed.ai/parse/$JOB_ID" \
-H "api-key: your-api-key"
{
"job_id": "a3f1c2d4-7e8b-4a9f-b2c1-123456789abc",
"upload_url": "https://upload.visionapi.unsiloed.ai/uploads/a3f1c2d4.../report.pdf?signature=...",
"expires_at": "2025-10-22T07:06:16Z",
"upload_method": "PUT",
"upload_headers": {
"Content-Type": "application/pdf"
}
}
| Feature | v1 (POST /parse) | v2 (POST /v2/parse/upload) |
|---|---|---|
| File delivery | Through API server | Direct via presigned URL |
| Max file size | Limited by server upload | Up to 5 GB via direct PUT |
| Upload speed | Bottlenecked by API server | Full client bandwidth |
| Concurrency | Shared server capacity | No server contention |
| Best for | Quick uploads, small files | Large files, high volume |
| Status | Cause | Action |
|---|---|---|
400 | Invalid or missing file_name, unsupported extension | Fix file_name and retry |
401 | Missing or invalid api-key (handled by authentication middleware) | Check your API key |
429 | Rate limit exceeded | Back off and retry after 1 second |
503 | Job queue is at capacity | Back off and retry after the Retry-After header value |
403 on upload | Missing or wrong headers, expired URL | Check upload_headers, get a new URL |
Job status Failed | Processing error | Check message field in the status response |
API key for authentication. Use 'Bearer <your_api_key>'
Request body for POST /v2/parse/upload. Configuration fields mirror the existing /parse multipart form fields.
File name with extension. Required. Determines content-type.
JSON object for chunk processing configuration.
Detect checkboxes using Swin Transformer Detection API. Defaults to false.
Error handling strategy: Continue (default) or Fail.
Seconds until the task and its output are deleted.
Extract structured data from charts and graphs. Defaults to false.
Transfer text color from the PDF text layer to OCR results. Defaults to false.
Attach hyperlink URLs from PDF annotations to OCR results. Defaults to false.
JSON object for LLM processing configuration.
Merge tables that span multiple pages into a single unified structure. Defaults to false.
OCR engine: UnsiloedBeta (default), UnsiloedHawk, or UnsiloedStorm.
OCR processing mode. auto_ocr (default) or force_ocr.
JSON object controlling which output fields are included in the response.
Page range to process. Formats: "1-5", "2,4,6", "[1,3,5]". Defaults to all pages.
JSON object for segment processing/analysis configuration.
Segment type naming convention: Unsiloed (default) or Other.
Segmentation strategy: smart_layout_detection (default) or page_by_page.
Use high-resolution images for cropping and post-processing. Defaults to true.
JSON array of segment types to validate with VLM. Example: ["Table","Formula"].
Legacy: validate table segments using VLM. Prefer validate_segments instead.
Extract and hyperlink bibliography citations in the markdown output. Defaults to false.
Upload URL created
Response from POST /v2/parse/upload.
RFC 3339 timestamp when upload_url expires.
Use this ID to poll GET /parse/{job_id} for status.
Headers the client MUST include in the PUT request.
Show child attributes
Always "PUT".
S3 presigned PUT URL. Valid until expires_at.