Skip to main content
POST /upload is the entry point for document processing. Every accepted upload returns a document_id, which becomes the handle for polling, streaming, and downstream bookkeeping.

Supported request shapes

Send a url

Use url when the document is already available at a fetchable HTTPS location.
{
  "url": "https://example.com/claims/123/scope.pdf",
  "file_name": "claim-123-scope.pdf",
  "xn_address": "restoration-team@example.xn"
}

Send file_base64

Use file_base64 when your application sends document bytes inline in the JSON payload. Inline base64 uploads are supported up to 50 MB.
{
  "file_base64": "JVBERi0xLjQKJ...",
  "file_name": "claim-123-scope.pdf",
  "xn_address": "restoration-team@example.xn"
}

Required fields

Every upload includes:
  • file_name: the original filename shown in downstream responses
  • xn_address: the Xactnet recipient address tied to the document
Exactly one of these payload fields must be present:
  • url
  • file_base64
If both fields are present, or if neither field is present, the API returns 422.

Encode a local file to base64

These examples show the local-file-to-base64 step that teams often use before constructing an inline upload request, including workflows that start with scanner images or other local files.

Python

from base64 import b64encode
from pathlib import Path

source_path = Path("./claim-123-scope.pdf")
file_base64 = b64encode(source_path.read_bytes()).decode("utf-8")

print(file_base64)

Node.js

import { readFile } from "node:fs/promises";

const sourcePath = "./claim-123-scope.pdf";
const fileBuffer = await readFile(sourcePath);
const fileBase64 = fileBuffer.toString("base64");

console.log(fileBase64);

curl

Use the base64 string as the file_base64 field in the upload request:
curl https://api.capout.ai/upload \
  -X POST \
  -H "content-type: application/json" \
  -H "capout-api-key: $CAPOUT_API_KEY" \
  -d '{
    "file_base64": "PASTE_BASE64_STRING_HERE",
    "file_name": "claim-123-scope.pdf",
    "xn_address": "restoration-team@example.xn"
  }'

What to store after upload

Persist at least these response fields on your side:
  • document_id
  • status
  • created_at
  • status_url
That gives you enough to start polling immediately and to join later status changes to your own job record.

Validation and retries

  • Review 422 responses first when an upload is rejected. They indicate request-shape problems such as sending both url and file_base64, sending neither field, or omitting a required field.
  • Retry upload failures from the same source document after correcting the request or transport problem.
  • Reuse the returned document_id for all follow-up status checks, realtime subscriptions, and internal job mapping.

Typical follow-up flow

  1. Upload the document.
  2. Store document_id on your internal job or claim record.
  3. Poll GET /status/{document_id} for simple backends, or open a realtime stream for richer UX.
  4. Optionally query GET /documents to reconcile the authenticated organization’s recent uploads.