Import a file by URL
- You are asking
- Copy this exact document.
- Endpoint
- POST /v1/buckets//files/import
- Identity
- Each import creates a new source.
- Lifecycle
- A snapshot, frozen at import time.
Calypso Context · Sources
A source is accepted if Calypso can read it and rejected at upload if it cannot. PDFs are read as text and as page images, images for what they depict, web pages as living sources. Every source lands in a bucket and reports one ready bit when it is searchable.
The example
Upload a file with one multipart request, or hand Calypso a URL. Either way the result is a source in a bucket, and ready tells you when an agent can cite it.
curl -X POST "https://api.calypso.so/v1/buckets/support-handbook/files" \
-H "Authorization: Bearer $CALYPSO_API_KEY" \
-H "Idempotency-Key: crm-doc-123" \
-F "file=@refund_policy_2026.pdf" \
-F "title=Refund policy 2026" \
-F "tags=policy,returns"
# 202 → { "id": "src_…", "ready": false, "status": "queued", … }What it reads
Modality decides how a source is read. Where the citation points decides what your users can check.
| Family | Types | Modality | Citations point at |
|---|---|---|---|
| Multimodal: text and page images | The page | ||
| Images | .png .jpg .jpeg | Image, read for content, not filename | The image |
| Documents | .docx | Text | The document |
| Text | .md .txt and other text/* | Text | The document |
| Data | .csv .json | Text | The document |
| Code | .py .ts .tsx .js .jsx .java .go .rs .sql .html .css .scss .yml .yaml .toml .ini .env .sh | Text | The document |
PDFs are the only document type read visually as well as textually, which is why they are the only ones that can cite a specific page. Excel files are not accepted: export the sheet to CSV before uploading.
A URL
You have a URL. There are two different things you might be asking Calypso to do with it, and they are different promises.
Pick the wrong door and the API tells you: a file import that receives HTML returns url_is_web_page, a page ingestion that receives a document returns url_is_file. Both point at the other door; force: true overrides.
How it works
PUT /v1/buckets/ is idempotent: it creates the bucket or returns the one that exists. Scripts can call it on every run.
One multipart call for a file, a direct-to-storage session for anything large, a JSON body for a URL, or a batch of up to 100 files.
Finalize means durably accepted, not searchable. Poll GET /v1/sources/ until ready is true, then test retrieval.
Readiness
An accepted upload is not yet an answerable source. The ready bit covers both indexing and bucket sync, so it is the only state a test needs.
1 / 4
The bytes are stored and the request is durable. A 202 here is not retrieval readiness.
2 / 4
The source has been read for its modality: text extracted, pages rendered, images described.
3 / 4
The bucket store that agents search has the source. bucket_sync_status shows the ladder if you need it.
4 / 4
ready: true. An agent bound to this bucket can retrieve and cite the source.
From the docs
| Max file size | 25 MB |
|---|---|
| Files per batch | 1 to 100, direct-to-storage sessions, one finalize |
| Rate limit | 5 create requests per second per team |
| Metadata | 8 KB per source, up to 20 tags |
| Readiness check | GET /v1/sources/{id} → ready: true |
| Web page identity | The normalized URL, one per team; a duplicate returns 409 with the existing source id |
| Excel | Not accepted. Export to CSV first. |
Questions and answers
Keep reading
Scoped, durable source memory. Provision by slug, bind to agents.
One default, any number of named agents with their own scope and policy.
A source on every answer: annotations by offset, a structured source list, native mode.
Retrieval without generation: the passages an answer would cite, ranked.
Yours, isolated: no training on your data, export or delete any time, keys with explicit scopes.
The reference this page is written from, with every endpoint and field.
Start today
Create a project API key, upload a PDF, and ask a question that cites the page.