Updated Apr 27, 2026
reference

Artifacts #

List, get, patch, delete, upload, download, status, cancel, rerun. Every endpoint under /artifacts.

The /artifacts/* endpoints cover the full lifecycle of an uploaded file: listing, metadata, downloads, lightweight status, cancel, rerun, the confirm-upload signal that tells the backend a presigned upload landed, and the direct multipart upload form.

GET /artifacts/

Paginated list of artifacts owned by the authenticated account.

ParamTypeDefaultNotes
pageinteger11-based page number.
sizeinteger50Items per page.
bash
curl -u "$DD_KEY:$DD_SECRET" \
  'https://api.datadistillers.com/api/v1/artifacts/?page=1&size=50'

Returns a Page[ArtifactListResponse]:

json
{
  "items": [
    {
      "id":            "art_b4d8c0f1",
      "filename":      "invoice-001.pdf",
      "artifact_type": "application/pdf",
      "artifact_size": 184320,
      "status":        "completed",
      "uploaded_at":   "2026-05-03T09:12:04Z",
      "confidence":    0.94,
      "needs_review":  false
    }
  ],
  "total": 2841,
  "page":  1,
  "size":  50,
  "pages": 57
}

GET /artifacts/{id}

Full record: metadata, status, processing timestamps, the most recent extraction result, and every job ever run against the artifact.

bash
curl -u "$DD_KEY:$DD_SECRET" \
  https://api.datadistillers.com/api/v1/artifacts/art_b4d8c0f1

See Artifacts for the response shape.

GET /artifacts/{id}/status

Lightweight status check for high-frequency polling. Returns just status, processed_at, and error: no metadata, no extraction result, no job array.

bash
curl -u "$DD_KEY:$DD_SECRET" \
  https://api.datadistillers.com/api/v1/artifacts/art_b4d8c0f1/status
json
{
  "id":             "art_b4d8c0f1",
  "status":         "processing",
  "processed_at":   null,
  "status_message": null
}

Prefer this over the full GET /artifacts/{id} when polling at sub-second intervals. Less bandwidth, less parsing, same source of truth.

PATCH /artifacts/{id}

Update mutable metadata. Three fields can be patched after upload:

bash
curl -u "$DD_KEY:$DD_SECRET" \
  -X PATCH https://api.datadistillers.com/api/v1/artifacts/art_b4d8c0f1 \
  -H 'Content-Type: application/json' \
  -d '{
    "filename":    "renamed.pdf",
    "description": "Q2 batch, Acme",
    "tags":        ["fy26", "q2", "acme"]
  }'
FieldConstraints
filenameMin length 3.
descriptionMax length 1000.
tagsFree-form string array.

Anything else (size, MIME, status, processing timestamps) is set by the platform and not user-mutable.

DELETE /artifacts/{id}

Removes the artifact record and its stored files immediately. No soft delete.

bash
curl -u "$DD_KEY:$DD_SECRET" \
  -X DELETE https://api.datadistillers.com/api/v1/artifacts/art_b4d8c0f1

Returns 204 No Content on success.

POST /artifacts/{id}/confirm-upload

The signal that tells the backend a presigned upload completed. The platform does not watch the upload bucket for S3 events; until you call this endpoint the artifact stays in pending_upload and the job is never enqueued.

When called, the platform:

  1. Verifies the object exists in S3 under the expected key.
  2. Flips the artifact status from pending_upload to uploaded.
  3. Flips the job status to queued_for_processing.
  4. Commits, then dispatches the worker to start processing.
bash
curl -u "$DD_KEY:$DD_SECRET" \
  -X POST https://api.datadistillers.com/api/v1/artifacts/art_b4d8c0f1/confirm-upload

Returns 200 OK and the updated artifact.

StatusMeaning
200The artifact moved to uploaded and the job was queued. Repeated calls return 200 without re-queueing.
404artifact_id doesn't exist or belongs to a different account.
409The artifact is past uploaded (already processing, completed, failed, etc.) or the S3 object is missing.

The endpoint is idempotent: calling it again on an already-confirmed artifact is safe and will not enqueue duplicate work. Use POST /artifacts/confirm-batch-upload/{batch_id} to confirm an entire batch in one call.

POST /artifacts/upload

Direct multipart upload, for cases where you'd rather send the file in one shot than do the submit / PUT / confirm three-step.

bash
curl -u "$DD_KEY:$DD_SECRET" \
  -X POST https://api.datadistillers.com/api/v1/artifacts/upload \
  -F 'file=@./invoice.pdf' \
  -F 'retention_policy=30d'

Form fields:

FieldRequiredNotes
fileyesThe file bytes.
retention_policynoOne of the RetentionPolicy values. Defaults to 30d.

Returns 202 Accepted + SingleUploadResponse (the artifact, with status uploaded). Unlike the presigned-URL flow, the upload bytes and the queue dispatch happen inline as part of the same request, so you do not need a separate confirm-upload call after this endpoint.

Use /extract for new integrations

/artifacts/upload is convenient for one-off scripts but doesn't accept template_id or extraction_schema; it relies on whatever pipeline default is set on the API key. New integrations should prefer /extract (followed by PUT and confirm-upload) for the explicit template-or-schema selection.

POST /artifacts/request-batch-upload and POST /artifacts/confirm-batch-upload/{batch_id}

Two-step batch upload. Like the single-file presigned flow, the platform only enqueues work after you confirm — but here one call confirms every file in the batch at once.

bash
# 1. Request URLs
curl -u "$DD_KEY:$DD_SECRET" \
  -X POST https://api.datadistillers.com/api/v1/artifacts/request-batch-upload \
  -H 'Content-Type: application/json' \
  -d '{
    "files": [
      { "filename": "a.pdf", "artifact_type": "application/pdf", "artifact_size": 1024 },
      { "filename": "b.pdf", "artifact_type": "application/pdf", "artifact_size": 2048 }
    ]
  }'
# returns batch_id and per-file upload URLs

# 2. PUT every file to its upload URL (concurrently).

# 3. Confirm; queues all uploaded files in one round-trip.
curl -u "$DD_KEY:$DD_SECRET" \
  -X POST https://api.datadistillers.com/api/v1/artifacts/confirm-batch-upload/bat_z9y8x7

Confirm is idempotent. Already-confirmed files are skipped; never-uploaded files stay pending. POST /batch is the friendly front-door that returns the same shape as request-batch-upload; both require this confirm call before anything is enqueued.

GET /artifacts/{id}/download

Returns a short-lived presigned URL to download an artifact or its extraction results.

ParamDefaultNotes
file_typejsonOne of raw (original file), json (structured result), md (markdown rendering).
bash
URL=$(curl -s -u "$DD_KEY:$DD_SECRET" \
  'https://api.datadistillers.com/api/v1/artifacts/art_b4d8c0f1/download?file_type=json' \
  | jq -r .download_url)

curl -s "$URL" > result.json

Response:

json
{
  "download_url": "https://s3.amazonaws.com/…?X-Amz-Signature=…",
  "artifact_id":  "art_b4d8c0f1",
  "filename":     "invoice-001.pdf",
  "expires_in":   300
}

Don't cache download_url. Re-request on each download.

POST /artifacts/{id}/rerun

Queues a fresh job against an artifact already in S3. Works for any terminal state: failed, cancelled, or completed.

bash
curl -u "$DD_KEY:$DD_SECRET" \
  -X POST https://api.datadistillers.com/api/v1/artifacts/art_b4d8c0f1/rerun

Returns 202 Accepted. A new Job record is created with a fresh job_id; the prior billing history is preserved on the artifact.

Returns 400 if the artifact's retention policy already purged the source file.

POST /artifacts/{id}/cancel

Cancels an in-flight processing job. Releases held balance, best-effort stops the GPU worker.

bash
curl -u "$DD_KEY:$DD_SECRET" \
  -X POST https://api.datadistillers.com/api/v1/artifacts/art_b4d8c0f1/cancel

Returns:

  • 200 OK: cancellation took effect.
  • 409 Conflict: job is already in a terminal state.

Errors

StatusCause
400Invalid request shape, or rerun against a purged artifact.
401Auth missing or invalid.
403Artifact belongs to a different account.
404artifact_id doesn't exist.
409Cancel against a terminal job, or confirm-upload against an artifact past uploaded / with no object in S3.
422Body or path parameter validation failed.
Esc
↑↓Navigate↵OpenEscClose