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.
- Each document has a SHA-256 file hash, computed when the upload is confirmed. The sale document list returns it as
fileHash. - The platform sorts the lowercase file hashes in ascending order and joins them.
- 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:
| Field | Meaning |
|---|---|
termsDocuments | The current terms documents: id, fileName, title and fileHash. |
termsDocumentsHash | The hash the platform derives from termsDocuments now. It is null when there is no terms document. |
termsHash | The 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.
POST /api/v2/addons/token-salescreates the sale in setup.POST /api/v2/addons/token-sales/{saleAddress}/document-uploadsreturns a presigned upload URL. SenddocumentType: "terms"andvisibility: "public". Upload the file to that URL.POST /api/v2/addons/token-sales/{saleAddress}/documentsconfirms the upload and stores the file hash.- Repeat steps 2 and 3 for each terms document.
PUT /api/v2/addons/token-sales/{saleAddress}/termssends the derived hash to the sale contract. The call needs wallet verification, like other sale writes. SendexpectedTermsHash, thetermsDocumentsHashyou showed the signer: when the documents changed since, the call is refused with422and 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.
- List.
GET /api/v2/addons/token-sales/{saleAddress}/documentslists the sale documents the caller may see. Keep the items withdocumentTypetermsandisLatesttrue. The sale read returns the same set astermsDocuments. - Download.
POST /api/v2/addons/token-sales/{saleAddress}/documents/{documentId}/downloadsreturns a short-lived download URL for one document. - Acknowledge.
POST /api/v2/addons/token-sales/{saleAddress}/term-acknowledgementsrecords the acknowledgement on chain for the caller's wallet. The sale read then returnshasAcknowledgedTerms: true. - Buy.
POST /api/v2/addons/token-sales/{saleAddress}/purchasessubmits 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
422when 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
422when the sale has terms documents but no recorded hash. - Either call answers with a retryable
503when 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 revert | Cause |
|---|---|
TermsNotSet | An acknowledgement or a purchase came before the issuer set the terms. |
TermsAlreadySet | The issuer set the terms a second time. The hash is fixed. |
TermsNotAccepted | The 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. |
Related
Onboard an investor
Create a user through the API, resolve the participant's identity wallet, register the identity under a country, and verify the investor with Sumsub.
Corporate actions
Declare a corporate action, preview its effect on holders, then confirm or abort. Covers chunked mint or burn, the in-flight limit, and redemption approval.