Upload the filing. Then ask it questions.
Financial PDFs are the worst case for document pipelines: 300 pages, scanned exhibits, tables that span page breaks. This API takes a PDF up to 50 MB over a resumable upload, runs validation and OCR, tells you exactly which pages it could not read, and then lets you reference the document by ID inside an AI query.
- 50 MB per document
- Resumable uploads
- Per-page failure reporting
curl https://stockup.cc/v1/documents \
-H "x-api-key: $STOCKUP_API_KEY" \
-H "content-type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"filename": "apple-10-k.pdf",
"size": 8412553,
"content_type": "application/pdf"
}'
# 201 → { document_id, upload_url,
# upload_method: "PUT",
# upload_headers, resumable: true,
# expires_at }unreadable_pages is explicitFour steps, then it is queryable.
POST /v1/documents with filename and size. You get a document_id and a private resumable upload_url back. Declaring the size up front means an oversized file is rejected before you spend bandwidth on it.
Upload directly to upload_url using the returned upload_headers. Because it is resumable, a 200 MB-per-hour office connection dropping mid-filing is an inconvenience rather than a restart.
POST /v1/documents/{documentId}/complete returns 202 and queues validation and OCR. Then poll GET /v1/documents/{documentId} for status and progress.
Once status is READY, pass the ID in the document_ids array of a POST /v1/query call. The model reasons over your document instead of recalling something similar from training data.
Eight states, because extraction genuinely has eight outcomes.
Most document APIs collapse this into processing then done or error, which forces you to guess whether a "done" document was fully readable. The states here are:
UPLOADING— bytes not yet completeVALIDATING— checking it is a real, intact PDFPROCESSING— extraction and OCR runningREADY— fully extractedREADY_WITH_WARNINGS— usable, but something was imperfectREJECTED— not accepted, with anerrorobjectEXPIRED— retention window elapsedDELETED— removed at your request
READY_WITH_WARNINGS is the one that saves you. A scanned exhibit on page 214 that OCR could not resolve will show up in unreadable_pages, so when your user asks about that exhibit you can say the page was unreadable rather than confidently answering from the pages that did parse.
{
"document_id": "doc_...",
"filename": "apple-10-k.pdf",
"status": "READY_WITH_WARNINGS",
"progress": 100,
"page_count": 312,
"unreadable_pages": [214, 215],
"warnings": [
"2 pages required OCR fallback"
],
"error": null,
"expires_at": "..."
}Ground the model in the file you uploaded.
curl https://stockup.cc/v1/query \
-H "x-api-key: $STOCKUP_API_KEY" \
-H "content-type: application/json" \
-d '{
"model": "quan-3.4",
"document_ids": ["doc_..."],
"messages": [{
"role": "user",
"content": "Summarise the risk factors that changed
versus the prior year, and quote the
segment revenue table verbatim."
}],
"stream": false
}'quan-3.4-deep-research for long multi-document investigations.This is the difference between an AI feature that reads your filing and one that produces a confident summary of a 10-K it half-remembers. The document is the ground truth for the request, and where a required figure is not present in the file, the intended behaviour is to say so rather than to supply a plausible number — the same principle behind unavailableInputs on the valuation endpoint.
You control retention.
expires_at; documents are not public objects.DELETE /v1/documents/{documentId} removes the PDF and the text extracted from it, not just the file record.Idempotency-Key header on upload creation so a retried request does not produce a duplicate document.GET /v1/document-jobs/{jobId} with its own states — QUEUED, RUNNING, SUCCEEDED, FAILED, CANCELED, EXPIRED — and a downloadable artifact when ready. Cancel a running job with DELETE.Integration details.
What file types are supported?
PDF. content_type accepts application/pdf and defaults to it. For filings you would otherwise scrape as HTML, see the SEC filing reader.
How should I poll for readiness?
Poll GET /v1/documents/{documentId} with backoff and read both status and progress. A 300-page scanned filing takes materially longer than a 20-page born-digital one, so avoid a fixed timeout tuned to the small case.
Can I attach several documents to one query?
document_ids is an array, so yes — comparing two years of the same filing is the obvious use. Longer multi-document work is what quan-3.4-deep-research exists for.
What happens if a document is rejected?
Status becomes REJECTED with a populated error object. Encrypted, corrupt, or non-PDF payloads are the usual causes.
How is this billed?
Document processing and the model call are separate costs. Model usage starts at $0.50 per million input tokens on Quan 3.4 L — a long filing is a lot of input tokens, so check pricing and the estimator before running a large corpus.
Upload a filing and query it today.
Start with 100,000 free Quan 3.4 L tokens. No card required.
Create a free API key →