Skip to main content
POST /upload is the entry point for generating Contractor and Carrier ESX files. Every accepted upload returns a document_id, which becomes the handle for polling, streaming, and downstream bookkeeping. If you are using an agent client such as ChatGPT, Claude, or Codex, see CapOut MCP instead. The MCP staged upload flow is separate from the public REST POST /upload contract documented here.

Supported request shapes

Send a url

Use url when the document is already available at a fetchable HTTPS location.

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 MiB.

Required fields

Every upload includes file_name, the original filename shown in downstream responses. Exactly one of these payload fields must be present:
  • url: an immediately downloadable HTTPS PDF
  • file_base64: PDF bytes encoded as base64
  • s3_path: a protected staged path returned by POST /upload-url
New integrations should omit xn_address and profile_code. They are optional, deprecated compatibility fields from the older XactNet delivery flow. CapOut now generates both Contractor (8D) and Carrier (5L) ESX files for every successful export, regardless of a legacy profile_code value. If multiple source fields are present, or if no source field is present, the API returns 422. Your request chooses the PDF source. CapOut chooses the protected AWS storage bucket and key used for intake; callers cannot override where the PDF is written inside CapOut’s AWS storage.

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

Node.js

curl

Use the base64 string as the file_base64 field in the upload request:

What to store after upload

Persist at least these response fields on your side:
  • document_id
  • status
  • created_at
  • status_url
  • download_url: stable Contractor download URL and the default link
  • contractor_download_url: explicit Contractor (8D) link
  • carrier_download_url: explicit Carrier (5L) link
That gives you enough to start polling immediately and to join later status changes to your own job record. The download URLs are returned while processing, but respond with 409 until export completion. Store the clean api.capout.ai links, not the temporary S3 URL reached after redirect.

Validation and retries

  • Review 422 responses first when an upload is rejected. They indicate request-shape problems such as sending multiple PDF sources, sending no source, or omitting file_name.
  • 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 while the export workflow completes.
  4. Optionally query GET /documents to reconcile the authenticated organization’s recent uploads.
  5. Give the user download_url for Contractor or carrier_download_url for Carrier after the export completes, and require their client to send the same organization’s capout-api-key when requesting it.
See Download ESX files for redirect, profile, and error behavior.