Skip to main content

Overview

Add documents to your Wolfia knowledge base programmatically. The upload flow has three steps: prepare the upload, upload the files using the returned URLs, and confirm to start processing.

How it works

1

Prepare

Send file metadata to get upload URLs for each file.
2

Upload

Upload each file to the returned URL using a multipart form POST.
3

Confirm

Send the source IDs back to confirm and start processing.

Prepare upload

URL: POST https://api.wolfia.com/v1/content-source/prepare-upload Authentication: API key required (see API overview for setup)
curl -X POST https://api.wolfia.com/v1/content-source/prepare-upload \
  -H "X-API-Key: wolfia-api-YOUR_KEY_HERE" \
  -H "Content-Type: application/json" \
  -d '{
    "files": [
      {
        "name": "security-policy.pdf",
        "size": 245760,
        "type": "application/pdf",
        "last_modified": 1700000000
      }
    ]
  }'

Request parameters

ParameterTypeRequiredDescription
filesarrayYesArray of file metadata objects
files[].namestringYesFilename including extension
files[].sizeintegerYesFile size in bytes
files[].typestringYesMIME type
files[].last_modifiedintegerYesLast modified timestamp (Unix seconds)
files[].contextstringNoDescription to help AI understand the document
files[].is_public_overridebooleanNoSet true to make the document publicly visible
files[].tag_idsarray of UUIDsNoTags to associate with the file

Supported file types

ExtensionMIME type (files[].type)
.pdfapplication/pdf
.docxapplication/vnd.openxmlformats-officedocument.wordprocessingml.document
.docapplication/msword
.mdtext/markdown
.pptxapplication/vnd.openxmlformats-officedocument.presentationml.presentation
.xlsxapplication/vnd.openxmlformats-officedocument.spreadsheetml.sheet
.xlsmapplication/vnd.ms-excel.sheet.macroenabled.12
.xlsapplication/vnd.ms-excel
.csvtext/csv
.txttext/plain
.jsonapplication/json
.htmltext/html
.pngimage/png
.jpgimage/jpeg
.webpimage/webp
.gifimage/gif
.emlmessage/rfc822

Response (200 OK)

Returns an upload URL and form fields for each file. Use these to upload the file content directly.
{
  "upload_urls": [
    {
      "source_id": "28c262e0-cfa4-442b-b193-21f94f200298",
      "upload_url": "https://storage.wolfia.com/",
      "fields": {
        "Content-Type": "application/pdf",
        "key": "...",
        "AWSAccessKeyId": "...",
        "policy": "...",
        "signature": "..."
      }
    }
  ]
}
FieldTypeDescription
upload_urls[].source_idstring (UUID)ID to use in the confirm step
upload_urls[].upload_urlstringURL to POST the file to
upload_urls[].fieldsobjectForm fields to include with the file upload

Upload files

Use the upload_url and fields from the prepare response. Include all fields as form fields, then append the file as the last field.
curl -X POST "UPLOAD_URL_FROM_PREPARE_RESPONSE" \
  -F "Content-Type=application/pdf" \
  -F "key=..." \
  -F "AWSAccessKeyId=..." \
  -F "policy=..." \
  -F "signature=..." \
  -F "[email protected]"
The file field must be the last field in the multipart form data.

Confirm upload

URL: POST https://api.wolfia.com/v1/content-source/confirm-upload Authentication: API key required (see API overview for setup)
curl -X POST https://api.wolfia.com/v1/content-source/confirm-upload \
  -H "X-API-Key: wolfia-api-YOUR_KEY_HERE" \
  -H "Content-Type: application/json" \
  -d '{
    "source_ids": ["28c262e0-cfa4-442b-b193-21f94f200298"]
  }'

Request parameters

ParameterTypeRequiredDescription
source_idsarray of stringsYesSource IDs from the prepare step

Response (200 OK)

{
  "message": "1 file(s) have been confirmed and queued for processing."
}

Integration example

Python: Upload a directory of documents

import os
import mimetypes
from pathlib import Path

import requests

WOLFIA_API_KEY = os.environ["WOLFIA_API_KEY"]
BASE_URL = "https://api.wolfia.com/v1"
HEADERS = {"X-API-Key": WOLFIA_API_KEY, "Content-Type": "application/json"}

SUPPORTED = {".pdf", ".docx", ".doc", ".md", ".pptx", ".ppt", ".xlsx", ".png", ".jpg", ".webp", ".gif"}


def upload_documents(directory: str):
    files = [f for f in Path(directory).iterdir() if f.suffix.lower() in SUPPORTED]
    if not files:
        print("No supported files found.")
        return

    # 1. Prepare
    metadata = [
        {
            "name": f.name,
            "size": f.stat().st_size,
            "type": mimetypes.guess_type(f.name)[0] or "application/octet-stream",
            "last_modified": int(f.stat().st_mtime),
        }
        for f in files
    ]

    resp = requests.post(f"{BASE_URL}/content-source/prepare-upload", headers=HEADERS, json={"files": metadata}, timeout=30)
    resp.raise_for_status()
    upload_urls = resp.json()["upload_urls"]

    # 2. Upload each file
    confirmed_ids = []
    for file_path, upload in zip(files, upload_urls):
        with open(file_path, "rb") as fh:
            form_fields = list(upload["fields"].items()) + [("file", (file_path.name, fh))]
            r = requests.post(upload["upload_url"], files=form_fields, timeout=120)

        if r.status_code in (200, 204):
            confirmed_ids.append(upload["source_id"])
            print(f"  Uploaded {file_path.name}")
        else:
            print(f"  Failed {file_path.name}: HTTP {r.status_code}")

    if not confirmed_ids:
        print("No files uploaded successfully.")
        return

    # 3. Confirm
    resp = requests.post(f"{BASE_URL}/content-source/confirm-upload", headers=HEADERS, json={"source_ids": confirmed_ids}, timeout=30)
    resp.raise_for_status()
    print(resp.json()["message"])


if __name__ == "__main__":
    upload_documents("/path/to/documents")

Error responses

Status CodeWhat it meansHow to fix
400No files provided or no valid files confirmedCheck your request body has a non-empty files array (prepare) or valid source_ids (confirm)
403Insufficient permissionsAPI key owner needs Expert or Admin role
422Invalid request parametersCheck required fields and data types
500Internal errorRetry with exponential backoff

Best practices

Send multiple files in one prepare call to reduce round trips.
If some files fail during upload, confirm only the successful ones. The confirm endpoint processes each ID independently.
Use the context field to describe what the document covers. This helps Wolfia extract more relevant knowledge.
{
  "name": "soc2-report-2024.pdf",
  "size": 512000,
  "type": "application/pdf",
  "last_modified": 1700000000,
  "context": "SOC 2 Type II audit report for FY2024"
}

Getting help

  • Check permissions: API key owner needs Expert or Admin role
  • Verify file types: Use a supported extension and correct MIME type
  • Contact support: Email [email protected]

Next steps