SettleMint
API referenceGuides

Sale terms and acknowledgement

Upload a Primary Offering's terms documents, record their hash once during setup, then list, download, acknowledge and buy as an investor.

Overview

A Primary Offering binds its terms to one hash. The platform derives that hash from the terms documents the issuer uploaded; no caller supplies it. An investor must acknowledge the hash on chain before the first purchase. A purchase without that acknowledgement reverts with TermsNotAccepted.

The hash is fixed during setup. The sale contract accepts it once, so a second set call reverts with TermsAlreadySet. Upload every terms document before you set the hash.

For the request and response fields of each route, use the v2 API explorer.

How the terms hash is derived

The terms set of a sale is its latest documents with documentType terms. A terms document is always public, so an investor can read it before they have any other access to the sale.

  1. Each document has a SHA-256 file hash, computed when the upload is confirmed. The sale document list returns it as fileHash.
  2. The platform sorts the lowercase file hashes in ascending order and joins them.
  3. The terms hash is the keccak256 of that joined value.

The order of upload does not change the result. You can compute the same hash from the same files outside the platform.

The sale read returns three terms fields:

FieldMeaning
termsDocumentsThe current terms documents: id, fileName, title and fileHash.
termsDocumentsHashThe hash the platform derives from termsDocuments now. It is null when there is no terms document.
termsHashThe hash recorded on the sale contract. It is null until the issuer sets the terms.

Once termsHash is set, the platform refuses to add or remove a terms document, so termsDocumentsHash stays equal to termsHash.

Issuer flow

The issuer needs the Sale Admin role on the sale token. Create the sale first: a document belongs to a sale address, which exists only after create. The create body takes no termsHash.

  1. POST /api/v2/addons/token-sales creates the sale in setup.
  2. POST /api/v2/addons/token-sales/{saleAddress}/document-uploads returns a presigned upload URL. Send documentType: "terms" and visibility: "public". Upload the file to that URL.
  3. POST /api/v2/addons/token-sales/{saleAddress}/documents confirms the upload and stores the file hash.
  4. Repeat steps 2 and 3 for each terms document.
  5. PUT /api/v2/addons/token-sales/{saleAddress}/terms sends the derived hash to the sale contract. The call needs wallet verification, like other sale writes. Send expectedTermsHash, the termsDocumentsHash you showed the signer: when the documents changed since, the call is refused with 422 and records nothing.

Uploading, replacing and removing a terms document needs the Sale Admin role. Other sale documents only need a sale management role, so a Funds Manager can still manage the brochure or FAQ.

The set-terms call is refused when the sale has no terms document, when the terms are already set or a set-terms transaction is still in flight, and after the sale leaves setup. Adding or removing a terms document is refused with 409 settlement.sale.TERMS_FIXED once the terms are set, while a set-terms or activation transaction is in flight, and after the sale leaves setup. A terms group can only be replaced by another terms document.

Activate the sale only after the terms are set. Activating a setup sale whose uploaded terms documents have no recorded hash is refused with 422.

In the Console, upload the terms documents on the sale's Marketing tab and choose Set Terms in the Manage menu or on the overview's terms tile. The create form no longer asks for a terms document, because the sale does not exist yet when the form is filled in.

Investor flow

An integration, such as an investor portal, follows four calls.

  1. List. GET /api/v2/addons/token-sales/{saleAddress}/documents lists the sale documents the caller may see. Keep the items with documentType terms and isLatest true. The sale read returns the same set as termsDocuments.
  2. Download. POST /api/v2/addons/token-sales/{saleAddress}/documents/{documentId}/downloads returns a short-lived download URL for one document.
  3. Acknowledge. POST /api/v2/addons/token-sales/{saleAddress}/term-acknowledgements records the acknowledgement on chain for the caller's wallet. The sale read then returns hasAcknowledgedTerms: true.
  4. Buy. POST /api/v2/addons/token-sales/{saleAddress}/purchases submits the purchase.

Treat each write as a request. Wait for the terminal settlement verdict of the acknowledgement before you submit the buy, as Idempotency and async settlement describes.

Both writes refuse when the documents and the recorded hash do not line up:

  • The acknowledgement is refused with 422 when the sale's current terms documents differ from the hash recorded on the sale contract. The investor would otherwise accept terms that are not the documents shown.
  • The purchase is refused with 422 when the sale has terms documents but no recorded hash.
  • Either call answers with a retryable 503 when the terms documents or the recorded hash cannot be read.

A sale without terms documents is not affected by these checks.

The platform does not check that the investor opened a document before they acknowledge. The acknowledgement proves that the wallet accepted the hash, not that the investor read the files. An integration that must show the documents first enforces that in its own flow.

Errors

Code or revertCause
TermsNotSetAn acknowledgement or a purchase came before the issuer set the terms.
TermsAlreadySetThe issuer set the terms a second time. The hash is fixed.
TermsNotAcceptedThe buyer has not acknowledged the terms hash.
settlement.sale.TERMS_FIXED (409)A terms document was added, replaced or removed after the terms were fixed.

On this page