# Token document uploads

Source: https://docs.settlemint.com/docs/developer-guides/api-integration/token-documents
Upload, confirm, list, download, and delete token or asset documents through the DALP API, SDK, and CLI.



DALP token document APIs manage files that belong to an asset, such as a
prospectus, term sheet, regulatory filing, compliance report, certificate,
reserve audit, or other asset evidence. The API uses the same two-step upload
pattern as other document flows:

1. Request a presigned upload URL for a token document.
2. Upload the file directly to storage using the returned method and headers.
3. Confirm the upload so DALP records the document against the token.
4. List, download, or delete the document later through the token document API.

This flow is for token or asset documents. Use the KYC document upload guide when
the file belongs to a user's KYC profile instead of an asset.

## Endpoints [#endpoints]

The token document API exposes these operations:

* `GET /api/v2/tokens/{tokenAddress}/documents` lists token documents with pagination, sorting, and filtering.
* `POST /api/v2/tokens/{tokenAddress}/document-uploads` returns a presigned upload URL.
* `POST /api/v2/tokens/{tokenAddress}/documents` confirms an uploaded file and creates the document record.
* `POST /api/v2/tokens/{tokenAddress}/documents/{documentId}/downloads` returns a secure download URL.
* `DELETE /api/v2/tokens/{tokenAddress}/documents/{documentId}` deletes a token document.

## Request an upload URL [#request-an-upload-url]

Request an upload URL before sending the file bytes. The request describes the
file and how it should be classified on the asset.

```ts
const upload = await client.token.documents.getUploadUrl({
  params: {
    tokenAddress: "0xTOKEN",
  },
  body: {
    documentType: "prospectus",
    fileName: "bond-prospectus.pdf",
    fileSize: 2_400_000,
    mimeType: "application/pdf",
    visibility: "public",
    title: "Bond prospectus",
    description: "Published prospectus for investor review",
  },
});
```

Supported MIME types are:

* `application/pdf`
* `image/jpeg`
* `image/png`
* `image/webp`
* `application/vnd.openxmlformats-officedocument.wordprocessingml.document`
* `application/vnd.openxmlformats-officedocument.spreadsheetml.sheet`

`fileSize` must be positive and no larger than 50 MiB.

## Upload the file bytes [#upload-the-file-bytes]

Upload the file directly to the returned URL. Use the returned method and
headers. Some storage backends include provider-specific headers in the upload
URL response.

```ts
await fetch(upload.data.uploadUrl, {
  method: upload.data.method,
  headers: upload.data.headers,
  body: fileBytes,
});
```

Do not replace the returned headers with only `Content-Type`. Provider-specific
headers are part of the upload contract.

## Confirm the uploaded document [#confirm-the-uploaded-document]

After the file upload succeeds, confirm the upload with the returned `objectKey`.
The confirmation creates the token document record and returns the stored document
metadata.

```ts
const document = await client.token.documents.confirmUpload({
  params: {
    tokenAddress: "0xTOKEN",
  },
  body: {
    objectKey: upload.data.objectKey,
    documentType: "prospectus",
    fileName: "bond-prospectus.pdf",
    fileSize: 2_400_000,
    mimeType: "application/pdf",
    visibility: "public",
    title: "Bond prospectus",
    description: "Published prospectus for investor review",
  },
});
```

The response includes the document `id`, `groupId`, `versionNumber`, `isLatest`,
`fileHash`, `uploadedAt`, and uploader metadata.

DALP calculates `fileHash` from the uploaded file bytes when the upload is
confirmed. Store that value in downstream systems when you need to reconcile that
an asset document record still points to the expected file.

Use `replaceGroupId` when a new upload should replace a previous document in the
same document group. The new record becomes the latest version for that group.

## Record document integrity claims [#record-document-integrity-claims]

Token document upload records and asset-level claims serve different purposes:

* The token document upload flow stores the file metadata, version group, and
  `fileHash` that belongs to the uploaded document record.
* An asset-level document-hash claim can reference a SHA-256 hash, document type,
  and file name without placing the document contents on-chain.

Use the upload flow to manage access, download links, and document versions. Use
an asset-level document-hash claim when an asset also needs an on-chain integrity
reference for a specific document.

## Choose document type and visibility [#choose-document-type-and-visibility]

Document types include asset evidence such as:

* `prospectus`
* `term_sheet`
* `legal_opinion`
* `regulatory_filing`
* `compliance_report`
* `annual_report`
* `financial_statement`
* `credit_rating`
* `covenant_agreement`
* `shareholder_agreement`
* `fund_fact_sheet`
* `subscription_agreement`
* `nav_report`
* `reserve_audit`
* `attestation_report`
* `reserve_composition`
* `certificate`
* `interest_schedule`
* `property_deed`
* `survey_report`
* `appraisal`
* `environmental_assessment`
* `title_insurance`
* `assay_certificate`
* `storage_receipt`
* `chain_of_custody`
* `insurance_certificate`
* `other`

Visibility controls who can access the document:

* `public`: visible to anyone who can access the token document surface.
* `holders`: visible to token holders.
* `restricted`: limited to explicitly allowed access paths.

Choose the narrowest visibility that fits the operating process and regulatory
basis for the document.

## List documents [#list-documents]

Use the list endpoint to reconcile published documents or populate an asset
document table.

```bash
curl --globoff "https://your-platform.example.com/api/v2/tokens/0xTOKEN/documents?page[limit]=50&sort=-uploadedAt" \
  -H "X-Api-Key: sm_dalp_xxxxxxxxxxxxxxxx"
```

The list endpoint supports pagination, sorting, filtering, and facets. Sortable
fields include `fileName`, `documentType`, `visibility`, `fileSize`, and
`uploadedAt`. Filterable fields are `fileName`, `documentType`, `visibility`,
`mimeType`, `isLatest`, `fileSize`, and `uploadedAt`.

Filter with the same collection filter shape used by the current list endpoints.
For example, request the latest public prospectuses uploaded after a cutoff time:

```bash
curl --globoff "https://your-platform.example.com/api/v2/tokens/0xTOKEN/documents?filter[documentType][eq]=prospectus&filter[visibility][eq]=public&filter[uploadedAt][gte]=2026-01-01T00:00:00.000Z" \
  -H "X-Api-Key: sm_dalp_xxxxxxxxxxxxxxxx"
```

The API only returns the latest non-deleted document records visible to the
caller. Public documents are visible through the token document surface. Holder
visibility requires a caller with an asset role, and restricted visibility
requires governance or admin rights.

## Download or delete a document [#download-or-delete-a-document]

Request a secure download URL when a user needs to retrieve the file:

```ts
const download = await client.token.documents.getDownloadUrl({
  params: {
    tokenAddress: "0xTOKEN",
    documentId: document.data.id,
  },
});
```

Delete a document only when it should no longer be available from the asset's
document record:

```ts
await client.token.documents.delete({
  params: {
    tokenAddress: "0xTOKEN",
    documentId: document.data.id,
  },
});
```

Keep the business reason and approval evidence for deletes in your operating
records. The delete call removes the document record from the API surface; it is
not a substitute for your regulated record-retention process.

## CLI commands [#cli-commands]

The DALP CLI exposes the same token document lifecycle:

```bash
dalp tokens documents list 0xTOKEN

dalp tokens documents get-upload-url \
  --address 0xTOKEN \
  --fileName bond-prospectus.pdf \
  --fileSize 2400000 \
  --mimeType application/pdf \
  --documentType prospectus \
  --visibility public

dalp tokens documents confirm-upload \
  --address 0xTOKEN \
  --objectKey uploads/token-documents/example-object-key \
  --documentType prospectus \
  --fileName bond-prospectus.pdf \
  --fileSize 2400000 \
  --mimeType application/pdf \
  --visibility public

dalp tokens documents get-download-url \
  --address 0xTOKEN \
  --documentId doc_123

dalp tokens documents delete \
  --address 0xTOKEN \
  --documentId doc_123
```

Use the API or SDK for the direct file upload step because the CLI returns the
presigned URL and object key; it does not upload the local file bytes for you.

## See also [#see-also]

* [KYC document uploads](/docs/developer-guides/api-integration/kyc-document-uploads)
* [Token lifecycle](/docs/developer-guides/api-integration/token-lifecycle)
* [Token holders and transfers](/docs/developer-guides/api-integration/token-holders-transfers)
