Skip to main content
File ingestion uses a presigned upload flow: create a document record, upload the bytes directly to object storage, then poll until background processing finishes.

Before you start

Set your API key, tenant, knowledge base, and file details:
export AUTOSAGE_KEY="sk_live_your_key_here"
export AUTOSAGE_URL="https://api.autosage.ai/api/v1"
export TENANT_ID="your_tenant_id"
export KB_ID="your_knowledge_base_id"
export FILE_PATH="./handbook.pdf"
export MIME_TYPE="application/pdf"
The examples below use jq to read the JSON response.

Presigned upload flow

1

Request an upload URL

Send the destination knowledge base, tenant, filename, MIME type, and exact byte size.
FILE_SIZE=$(wc -c < "$FILE_PATH" | tr -d ' ')
FILE_NAME=$(basename "$FILE_PATH")

PRESIGN_RESPONSE=$(curl --fail --silent --show-error \
  -X POST "$AUTOSAGE_URL/documents/presign" \
  -H "Authorization: Bearer $AUTOSAGE_KEY" \
  -H "Content-Type: application/json" \
  -d "$(jq -n \
    --arg kb_id "$KB_ID" \
    --arg tenant_id "$TENANT_ID" \
    --arg filename "$FILE_NAME" \
    --arg mime_type "$MIME_TYPE" \
    --argjson size_bytes "$FILE_SIZE" \
    '{kb_id: $kb_id, tenant_id: $tenant_id, filename: $filename, mime_type: $mime_type, size_bytes: $size_bytes}')")

DOCUMENT_ID=$(printf '%s' "$PRESIGN_RESPONSE" | jq -r '.document_id')
UPLOAD_URL=$(printf '%s' "$PRESIGN_RESPONSE" | jq -r '.upload_url')

printf 'Document: %s\n' "$DOCUMENT_ID"
The response has this shape:
{
  "document_id": "2e7a1aa0-...",
  "upload_url": "https://...",
  "expires_at": "2026-07-10T12:00:00.000Z"
}
2

Upload the file bytes

Put the file at upload_url with the same Content-Type used in the presign request. The storage request does not use your AutoSage bearer key.
curl --fail --silent --show-error \
  -X PUT "$UPLOAD_URL" \
  -H "Content-Type: $MIME_TYPE" \
  --data-binary "@$FILE_PATH"
Processing starts automatically after the upload arrives.
3

Poll until processing finishes

while true; do
  STATUS_RESPONSE=$(curl --fail --silent --show-error \
    "$AUTOSAGE_URL/documents/status?document_id=$DOCUMENT_ID" \
    -H "Authorization: Bearer $AUTOSAGE_KEY")

  STATUS=$(printf '%s' "$STATUS_RESPONSE" | jq -r '.status')
  printf 'Status: %s\n' "$STATUS"

  case "$STATUS" in
    processed) break ;;
    failed) printf '%s\n' "$STATUS_RESPONSE" >&2; exit 1 ;;
    *) sleep 3 ;;
  esac
done
Treat upload_url as a short-lived secret and use it before expires_at. Upload the bytes exactly once with the intended MIME type; request a new URL if the original one expires.

Processing statuses

StatusMeaning
pending_uploadThe document record exists and is waiting for file bytes
queuedThe upload arrived and background processing is queued
processingThe file is being parsed, chunked, embedded, and indexed
processedThe document is searchable
failedProcessing ended unsuccessfully; inspect the document and reprocess or replace it
AutoSage supports PDFs, including scanned PDFs; plain text, Markdown, HTML, CSV, and JSON; Word, Excel, and PowerPoint files; common audio formats; and common image formats. Files can be up to 500 MB, subject to the tenant’s document-count and storage quotas.
Quota checks happen before the upload URL is issued. A tenant over its document or storage allowance receives a 403 response with a clear message.

URL ingestion and document maintenance

MethodPathPurpose
POST/documents/upload-urlScrape one URL and queue it as a document
POST/documents/upload-url-siteDiscover up to about 25 pages from a site before ingestion
POST/documents/:id/reprocessQueue an existing document for processing again
GET/documents/:id/downloadCreate a temporary download URL
DELETE/documents/:idRemove the document from search and clean up its stored data
Wait for processed before querying the knowledge base. Remove failed or abandoned uploads you no longer need because their document records and stored bytes count toward tenant quotas.
For the complete background pipeline, see Ingestion lifecycle. For endpoint schemas, see the Documents API.

Next steps

Ingestion lifecycle

Follow parsing, chunking, embedding, indexing, and cleanup.

RAG lifecycle

See how processed content becomes cited evidence.