curl -X POST 'https://api.anyformat.ai/v3/workflows/0686bb97-8c30-70f0-8000-97669e000eb8/dataset/upload/' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Idempotency-Key: 5f2b6c3e-8a1d-4f7e-9c0b-1a2b3c4d5e6f' \
-F 'files=@/path/to/invoice_001.pdf' \
-F 'ground_truth={"invoice_no": "INV-1", "total": "90.00"}'
from anyformat.sdk import Client, DatasetDocument
client = Client(api_key="YOUR_API_KEY")
workflow_id = "0686bb97-8c30-70f0-8000-97669e000eb8"
# One document with ground truth.
upload = client.upload_to_dataset(
workflow_id,
"invoice_001.pdf",
ground_truth={"invoice_no": "INV-1", "total": "90.00"},
)
print(upload.document_packet_id, upload.ground_truth_saved)
# Bulk: one atomic call per document.
uploads = client.upload_documents_to_dataset(
workflow_id,
[
DatasetDocument(file="invoice_001.pdf", ground_truth={"invoice_no": "INV-1"}),
DatasetDocument(file="invoice_002.pdf", ground_truth={"invoice_no": "INV-2"}),
],
)
interface DatasetUpload {
document_packet_id: string;
files: { id: string; name: string; original_name: string | null }[];
ground_truth_saved: boolean;
}
const workflowId = '0686bb97-8c30-70f0-8000-97669e000eb8';
const formData = new FormData();
formData.append('files', fileInput.files[0]);
formData.append('ground_truth', JSON.stringify({ invoice_no: 'INV-1', total: '90.00' }));
const response = await fetch(
`https://api.anyformat.ai/v3/workflows/${workflowId}/dataset/upload/`,
{
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Idempotency-Key': crypto.randomUUID(),
},
body: formData,
}
);
if (!response.ok) {
throw new Error(`API error: ${response.status}`);
}
const upload: DatasetUpload = await response.json();
console.log(upload.document_packet_id, upload.ground_truth_saved);
{
"document_packet_id": "069dcc2c-e14c-7606-8000-2ee4fb17b4e1",
"files": [
{ "id": "069dcc2c-e14c-7606-8000-2ee4fb17b4e2", "name": "invoice_001.pdf", "original_name": null }
],
"ground_truth_saved": true
}
Upload to Dataset
Upload one document (+ optional ground truth) into a workflow dataset
curl -X POST 'https://api.anyformat.ai/v3/workflows/0686bb97-8c30-70f0-8000-97669e000eb8/dataset/upload/' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Idempotency-Key: 5f2b6c3e-8a1d-4f7e-9c0b-1a2b3c4d5e6f' \
-F 'files=@/path/to/invoice_001.pdf' \
-F 'ground_truth={"invoice_no": "INV-1", "total": "90.00"}'
from anyformat.sdk import Client, DatasetDocument
client = Client(api_key="YOUR_API_KEY")
workflow_id = "0686bb97-8c30-70f0-8000-97669e000eb8"
# One document with ground truth.
upload = client.upload_to_dataset(
workflow_id,
"invoice_001.pdf",
ground_truth={"invoice_no": "INV-1", "total": "90.00"},
)
print(upload.document_packet_id, upload.ground_truth_saved)
# Bulk: one atomic call per document.
uploads = client.upload_documents_to_dataset(
workflow_id,
[
DatasetDocument(file="invoice_001.pdf", ground_truth={"invoice_no": "INV-1"}),
DatasetDocument(file="invoice_002.pdf", ground_truth={"invoice_no": "INV-2"}),
],
)
interface DatasetUpload {
document_packet_id: string;
files: { id: string; name: string; original_name: string | null }[];
ground_truth_saved: boolean;
}
const workflowId = '0686bb97-8c30-70f0-8000-97669e000eb8';
const formData = new FormData();
formData.append('files', fileInput.files[0]);
formData.append('ground_truth', JSON.stringify({ invoice_no: 'INV-1', total: '90.00' }));
const response = await fetch(
`https://api.anyformat.ai/v3/workflows/${workflowId}/dataset/upload/`,
{
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Idempotency-Key': crypto.randomUUID(),
},
body: formData,
}
);
if (!response.ok) {
throw new Error(`API error: ${response.status}`);
}
const upload: DatasetUpload = await response.json();
console.log(upload.document_packet_id, upload.ground_truth_saved);
{
"document_packet_id": "069dcc2c-e14c-7606-8000-2ee4fb17b4e1",
"files": [
{ "id": "069dcc2c-e14c-7606-8000-2ee4fb17b4e2", "name": "invoice_001.pdf", "original_name": null }
],
"ground_truth_saved": true
}
ground_truth for that packet. Creation is all-or-nothing. One rejected file or a ground-truth failure fails the whole request and stores nothing. An unsupported type and disguised bytes both cause a rejection.
Send the files as multipart form data under the files field, repeating the field for a multi-file document. The response returns a stable document_packet_id. The presigned upload-slot ids stay hidden.
The client orchestrates bulk ingestion: loop this endpoint, one call per document. The API has no batch endpoint, so every call stays bounded, atomic and independently retryable. The SDKs provide the per-document loop.
Filenames are unique within a workflow. Under the default, on_conflict=error, a document whose name collides with a live dataset member fails with 409. The response lists each conflict and the name it would take. No rename is ever silent. Pass on_conflict=rename to rename the collision instead. The returned file’s name is then the name it landed under, and original_name holds the name you sent. original_name is null when no rename happened.
Ground truth arrives in the optional ground_truth field. It holds the expected document for this document packet, as a JSON-encoded object sent as a string, because multipart carries no nested objects. The keys are the workflow schema’s field identifiers. Use persistent_id; the API also accepts sanitized_name. A scalar field maps to string | null, and a table or object field maps to an array of row objects. Ground truth attaches to the workflow’s current version. On success, ground_truth_saved is true.
Retries are safe with Idempotency-Key. Pass any unique string. Retrying the request with the same key replays the original document packet, so the API registers no duplicate document. See Idempotency.
curl -X POST 'https://api.anyformat.ai/v3/workflows/0686bb97-8c30-70f0-8000-97669e000eb8/dataset/upload/' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Idempotency-Key: 5f2b6c3e-8a1d-4f7e-9c0b-1a2b3c4d5e6f' \
-F 'files=@/path/to/invoice_001.pdf' \
-F 'ground_truth={"invoice_no": "INV-1", "total": "90.00"}'
from anyformat.sdk import Client, DatasetDocument
client = Client(api_key="YOUR_API_KEY")
workflow_id = "0686bb97-8c30-70f0-8000-97669e000eb8"
# One document with ground truth.
upload = client.upload_to_dataset(
workflow_id,
"invoice_001.pdf",
ground_truth={"invoice_no": "INV-1", "total": "90.00"},
)
print(upload.document_packet_id, upload.ground_truth_saved)
# Bulk: one atomic call per document.
uploads = client.upload_documents_to_dataset(
workflow_id,
[
DatasetDocument(file="invoice_001.pdf", ground_truth={"invoice_no": "INV-1"}),
DatasetDocument(file="invoice_002.pdf", ground_truth={"invoice_no": "INV-2"}),
],
)
interface DatasetUpload {
document_packet_id: string;
files: { id: string; name: string; original_name: string | null }[];
ground_truth_saved: boolean;
}
const workflowId = '0686bb97-8c30-70f0-8000-97669e000eb8';
const formData = new FormData();
formData.append('files', fileInput.files[0]);
formData.append('ground_truth', JSON.stringify({ invoice_no: 'INV-1', total: '90.00' }));
const response = await fetch(
`https://api.anyformat.ai/v3/workflows/${workflowId}/dataset/upload/`,
{
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Idempotency-Key': crypto.randomUUID(),
},
body: formData,
}
);
if (!response.ok) {
throw new Error(`API error: ${response.status}`);
}
const upload: DatasetUpload = await response.json();
console.log(upload.document_packet_id, upload.ground_truth_saved);
{
"document_packet_id": "069dcc2c-e14c-7606-8000-2ee4fb17b4e1",
"files": [
{ "id": "069dcc2c-e14c-7606-8000-2ee4fb17b4e2", "name": "invoice_001.pdf", "original_name": null }
],
"ground_truth_saved": true
}
Authorizations
API key issued from app.anyformat.ai/api-key. Send as Authorization: Bearer <key>.
Headers
Optional caller-supplied key (Stripe convention). Retrying the request with the same key replays the original document packet — no duplicate document is registered.
Path Parameters
Body
1..100 files forming ONE document (one document packet in the dataset).
Optional JSON-encoded object: the expected document for this document packet. Keys are the workflow schema's field identifiers — advertise persistent_id (the API also accepts sanitized_name). A scalar field maps to string | null; a table/object field maps to an array of row objects. Ground truth attaches to the workflow's current version.
How to handle an uploaded filename that already exists in the workflow (filenames are unique within a workflow). error (the default) rejects the whole request with 409 and lists the conflicting names, so a rename is never silent — the caller must opt in. rename accepts the collision and lets the server auto-rename the file by inserting a (n) counter before the extension (invoice.pdf → invoice (1).pdf).
error, rename Response
Successful Response
Response for POST /v3/workflows/{workflow_id}/dataset/upload/.
One dataset document packet, all-or-nothing. document_packet_id is the
stable handle for the deferred ground-truth-edit follow-up.
Unique identifier of the created dataset document packet (hyphenated UUID).
"069dcc2c-e14c-7606-8000-2ee4fb17b4e1"
Files in the packet, in the order they were provided.
Show child attributes
Show child attributes
Whether ground truth was supplied and saved for this document packet.

