SettleMint
Developer guidesAPI integration

Token document uploads

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.

Before you start

You need:

  • a DALP API key with access to the token document operations.
  • the token contract address for the asset that owns the document.
  • the asset profile, because DALP validates documentType against the profile.
  • the file name, MIME type, size in bytes, and visibility level before requesting an upload URL.

Flow at a glance

The upload URL and confirmation calls are separate because the file bytes go directly to storage. DALP records the token document only after you confirm the returned objectKey.

Rendering diagram...

If the direct storage upload fails, do not confirm the document. Request a fresh upload URL when the returned expiresAt time has passed or when storage rejects the returned headers.

Endpoint reference

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 before sending the file bytes. The request describes the file and how it should be classified on the asset.

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",
  },
});

The upload URL request accepts these fields:

FieldRequiredDescription
documentTypeYesToken document type. Use a value allowed by the asset profile.
fileNameYesFile name, up to 255 characters.
fileSizeYesInteger size in bytes. The value must be positive and no larger than 50 MiB.
mimeTypeYesOne of the supported MIME types below.
visibilityYespublic, holders, or restricted.
titleNoDisplay title, up to 500 characters.
descriptionNoDescription, up to 2,000 characters.

Supported MIME types are:

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

The upload URL response includes:

FieldDescription
uploadUrlPresigned URL for the direct file upload.
objectKeyStorage object key to send in the confirmation request.
expiresAtExpiry timestamp for the presigned URL.
methodUpload method. Token document uploads use PUT.
headersHeaders that must be sent with the direct storage upload.

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.

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

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.

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 confirmation request repeats the file metadata and adds objectKey. It also accepts replaceGroupId when the new upload replaces an earlier document in the same version group.

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.

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 the document type from the token's asset profile, not from the full token document catalog. DALP uses the asset type to narrow the choices shown in the dapp upload dialog, so a stablecoin exposes reserve evidence choices while a precious metal exposes assay, storage, custody-chain, and insurance choices.

Asset profileDocument type choices
Bondsprospectus, term_sheet, legal_opinion, regulatory_filing, compliance_report, annual_report, financial_statement, credit_rating, covenant_agreement, interest_schedule, certificate, other
Equityprospectus, term_sheet, legal_opinion, regulatory_filing, compliance_report, annual_report, financial_statement, shareholder_agreement, certificate, other
Fundsprospectus, term_sheet, legal_opinion, regulatory_filing, compliance_report, annual_report, financial_statement, fund_fact_sheet, subscription_agreement, nav_report, certificate, other
Stablecoinslegal_opinion, regulatory_filing, compliance_report, reserve_audit, attestation_report, reserve_composition, certificate, other
Depositsterm_sheet, legal_opinion, regulatory_filing, compliance_report, financial_statement, interest_schedule, certificate, other
Real estatelegal_opinion, regulatory_filing, compliance_report, appraisal, property_deed, survey_report, environmental_assessment, title_insurance, insurance_certificate, certificate, other
Precious metalslegal_opinion, regulatory_filing, compliance_report, assay_certificate, storage_receipt, chain_of_custody, insurance_certificate, certificate, other

For API and CLI integrations, send a documentType value that belongs to the asset profile you are updating. For example, use reserve_audit, attestation_report, or reserve_composition for stablecoin reserve evidence, and use assay_certificate, storage_receipt, or chain_of_custody for precious metal evidence. Use other only when the document does not fit a more specific type.

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

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

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:

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.

The list response uses the standard collection shape with data, meta, and links. Each document row includes the document identifiers, token address, type, visibility, group version metadata, file metadata, optional title and description, fileHash, uploadedAt, and uploader metadata.

Download or delete a document

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

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:

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

The DALP CLI exposes the same token document lifecycle:

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

On this page