> ## Documentation Index
> Fetch the complete documentation index at: https://docs.useasterisk.com/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> Document only operations in the linked OpenAPI contract: the source-data ingestion operations and the source-scoped outbound webhook management operations.
> Treat the generated OpenAPI document as authoritative for request fields. Never invent compatibility fields, alternate endpoints, or additional source models.
> Preserve explicit nulls, decimal strings, timestamps, source identifiers, immutable version identifiers, and document-version links exactly as defined.

# Documents

> Upload a file once and reference its immutable version from customers or transactions.

A Document is a file supplied by your system, such as an identity document, application form, or
transaction attachment. The stable Document identifies the file across time; each accepted upload
creates an immutable DocumentVersion containing the supplied bytes or URL reference and metadata.

## What to send

| Field | Meaning |
| - | - |
| `externalId` | Stable identifier for the document in your system |
| `documentType` | Your classification, or `null` if unavailable |
| `displayName` | Human-readable filename or label, or `null` |
| `contentType` | MIME type of the uploaded bytes |
| `contentBase64` | Base64-encoded file content; omit when sending `sourceUrl` |
| `sourceUrl` | HTTP(S) document URL; omit when sending `contentBase64` |
| `effectiveAt` | When this version became true in your system |
| `sourceExternalId` | Optional secondary source identifier |
| `changeReason` | Optional explanation for a later version |

## Upload a document

```bash theme={null}
curl --request POST \
  --url https://api.sandbox.useasterisk.com/api/ingestion/documents \
  --header "Authorization: Bearer $KARSA_API_TOKEN" \
  --header "Idempotency-Key: document-example-001-create" \
  --header "Content-Type: application/json" \
  --data '{
    "externalId": "document-example-001",
    "sourceExternalId": null,
    "documentType": "GOVERNMENT_ID",
    "displayName": "Identity card front",
    "contentType": "image/jpeg",
    "contentBase64": "a2Fyc2E=",
    "effectiveAt": "2026-08-21T12:00:00Z",
    "changeReason": null
  }'
```

```json theme={null}
{
  "outcome": "CREATED",
  "resourceId": "document_resource_example_01",
  "versionId": "document_version_example_01",
  "currentVersionId": "document_version_example_01"
}
```

Save the returned `versionId`. A customer or transaction links the exact DocumentVersion it was
submitted with, rather than a mutable pointer that could later refer to different bytes.

## Submit a URL reference

Send exactly one of `contentBase64` or `sourceUrl`. Both and neither are rejected. The other
metadata fields stay the same:

```json theme={null}
{
  "externalId": "document-example-001",
  "documentType": "GOVERNMENT_ID",
  "displayName": "Identity card front",
  "contentType": "image/jpeg",
  "sourceUrl": "https://files.example.com/documents/id-front.jpg",
  "effectiveAt": "2026-08-21T12:00:00Z"
}
```

URLs may be signed or unsigned and are retained exactly as submitted (up to 8,192 characters).
Use absolute HTTP(S) URLs without embedded username/password, fragments, whitespace, or backslashes. Prefer HTTPS.
Karsa records a `PENDING_DOWNLOAD` version and returns the existing resource/version response (201 for a new document; 200 for a new version).
It does **not** fetch, sign, or verify the URL at ingestion time. No stored file or verified size
is claimed, and the reference is not available evidence for a KYB dossier.

Signing and downloading require a later authorized provider integration. A private URL cannot
be signed using Karsa's own S3 credentials unless Karsa has access to that object. Signed URLs
can expire; prefer stable unsigned references when the provider supports signing them later.
Treat submitted signed URLs as credentials. They are not returned in the ingestion response,
and receipts contain a hash instead of the URL. No public URL-read endpoint is added here.

To supply the downloaded bytes later, submit `contentBase64` under the same `externalId` with
a new idempotency key. This creates a new `AVAILABLE` version; existing links to an earlier
pending version remain pinned to that version.

## Versioning and deduplication

Send the same `externalId` when the same source document receives corrected content or metadata.
Use a new idempotency key for the changed snapshot. Retrying the same logical upload uses the same
idempotency key and does not create another version.

Document uploads do not accept arbitrary `customData`. Send only the fields in the contract.

## Related

* [Customers](/concepts/customers): link identity and onboarding documents
* [Transactions](/concepts/transactions): link transaction attachments
* [How records fit together](/concepts/source-schema): stable resources and immutable versions


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.