SettleMint
Tokens

Token creation progress stream

Subscribe to a server-sent events stream that reports token-creation deployment progress for one async create request, then handle each phase event until the deployment completes or fails.

When an integration creates a token, it can watch the deployment run instead of polling for a final state. POST /api/v2/tokens accepts the request and returns a transactionId. Open the progress stream for that id to receive each deployment phase as it starts and finishes. An operator then sees the contract deploy, permissions grant, and setup steps move in real time, rather than waiting on a single terminal poll.

Use this reference when your client drives token creation over the API and wants a live progress view, such as the deployment timeline in a console. For a client that does not need live updates, keep polling the create request's status URL instead, as described in Token lifecycle.

Start a creation request first

The stream follows an existing creation request. Create the token with POST /api/v2/tokens and read the transactionId from the asynchronous queue response.

On a network that charges a gas token, set gasPauseEnabled to true in the create request to make a deploy survive a creator-wallet gas shortfall. With the opt-in, a shortfall during deployment pauses the workflow and surfaces a funding requirement on this stream, then resumes once the wallet is funded. Without it, the deploy follows the default behaviour and ends with a terminal failure when the wallet runs short. See Funding pauses during deployment for the events the stream sends while paused.

{
  "transactionId": "01934567-89ab-7def-8123-456789abcdef",
  "status": "QUEUED",
  "statusUrl": "/api/v2/transaction-requests/01934567-89ab-7def-8123-456789abcdef"
}

The transactionId is the key for the stream. For the full create request, prerequisites, and idempotency rules, see Token lifecycle.

Endpoint

GET /api/v2/tokens/create/{transactionId}/stream

Pass the transactionId from the create response as the path parameter. The stream reports progress for that one creation request. It is read-only: it does not move assets or change the deployment, and it reads the creation workflow's status without altering it.

The stream serves a browser session that powers the Console, so it requires a same-origin request. Reuse the session that submitted the create request, and keep its cookies on the stream connection.

curl -N "$DALP_API_URL/api/v2/tokens/create/01934567-89ab-7def-8123-456789abcdef/stream" \
  -H "Accept: text/event-stream" \
  -H "Origin: ${DALP_API_URL}" \
  -b /tmp/dalp-session.cookies

A request for a transactionId that the caller's organisation cannot see, or a cross-origin request, returns the same not-found result. The stream does not reveal whether the id exists in another organisation, so a caller cannot probe for creation requests outside its own scope.

Event protocol

The stream emits deployment events as server-sent events. It sends the full phase tree once on connect, then sends updates as phases change, and ends with a single terminal event.

Event typePayload fieldsClient handling
treenodesReplace the local phase tree with the received tree.
updatenodeId, status, optional errorPatch the matching phase in the local tree.
requirement-requiredrequirementId, kind, payloadThe deploy paused and needs a manual step, such as funding the creator wallet. Show the requirement and keep listening.
requirement-resolvedrequirementId, kind, optional resolutionThe requirement cleared and the deploy resumed. Clear the requirement view and keep listening.
requirement-expiredrequirementId, kind, finalShortfallWei, recoveryGuidanceThe requirement was not met in time. Read recoveryGuidance and expect a terminal failure.
completesuccess, optional failedStepsStop listening. When success is false, read failedSteps for the failure.
errormessage, errorStop listening and inspect the public Platform API error payload.

Each node in the tree carries an id, a label, a type, and a status. The phases cover the steps that apply to the token, such as deploying the token contract, granting permissions, issuing claims, and, when they apply, submitting the initial price feed and unpausing the token. Steps that do not apply to the token do not appear. Key your client off id, type, and status rather than the display label, because labels can vary by deployment state.

A node status is one of pending, in-progress, completed, or failed.

event: message
data: {"type":"tree","nodes":[{"id":"creating","label":"Deploying Token","type":"factory","status":"pending"},{"id":"granting-permissions","label":"Granting Permissions","type":"role","status":"pending"},{"id":"issuing-claims","label":"Issuing Claims","type":"identity","status":"pending"}]}

event: message
data: {"type":"update","nodeId":"creating","status":"in-progress"}

event: message
data: {"type":"update","nodeId":"creating","status":"completed"}

event: message
data: {"type":"complete","success":true}

Funding pauses during deployment

On a network that charges a gas token, a signer wallet can run short of the network gas token partway through a deploy. When the create request set gasPauseEnabled to true, the workflow does not fail. It pauses at the funding step, sends a requirement-required event, and waits for the wallet to receive funds. This keeps a deploy recoverable on public and other non-zero-gas chains instead of losing the run to a transient shortfall.

A deploy can use more than one signer wallet, so it can pause for more than one. The token contract deploy and the initial price feed are broadcast from the token creator wallet, while the price feed value submission is broadcast from the organisation's feed submission wallet. Each step funds its own signer, so a single deploy can raise a separate funding pause for each wallet. The role field in the payload names which wallet the current pause is waiting on, so read it on every requirement-required event rather than assuming one funding target for the whole deploy.

A requirement-required event carries a requirementId, a kind, and a payload. The kind is gas for a funding pause. The payload names the funding target and the amounts a client needs to top up the wallet.

Payload fieldMeaning
roleWhich wallet must be funded: the token creator wallet for the contract deploy and price feed creation, or the organisation feed submission wallet for the price feed value submission.
chainIdThe numeric chain id the deploy runs on.
chainNameThe human-readable network name.
addressThe wallet address to fund.
tokenSymbolThe gas token symbol for that network.
shortfallWeiThe amount still missing, in wei, as a decimal string. Send at least this much.
recommendedTotalWeiThe target wallet balance that funds the deploy and leaves headroom, in wei.

The payload carries more fields than the table lists, including amounts the Console uses to render its funding screen. Read the fields by name rather than validating the payload against a closed schema, so a future field does not break a strict client.

The example below is abbreviated to the fields most clients read. A live event carries the full payload.

event: message
data: {"type":"requirement-required","requirementId":"...","kind":"gas","payload":{"role":"token-creator-eoa","chainId":1,"chainName":"Ethereum","address":"0x71C7656EC7ab88b098defB751B7401B5f6d8976F","tokenSymbol":"ETH","shortfallWei":"4200000000000000","recommendedTotalWei":"21000000000000000"}}

The example above shows a pause on the token creator wallet. A pause on the organisation feed submission wallet carries the same shape with a different role value. Match the role to the wallet your client funds rather than hard-coding a single value.

Send the network gas token to the address. Transfer at least shortfallWei, or top the wallet up to recommendedTotalWei to cover the deploy with headroom. The workflow polls the wallet, so a client does not call back to confirm the transfer. Once the balance covers the requirement, the stream sends a requirement-resolved event with the same requirementId and resumes the deployment with no resubmission. Treat this event as the signal that the pause cleared; the deploy phases continue with the usual update events.

event: message
data: {"type":"requirement-resolved","requirementId":"...","kind":"gas"}

If the wallet is not funded in time, the stream sends a requirement-expired event with finalShortfallWei and a recoveryGuidance string, then the deploy ends with a terminal complete event where success is false. Read recoveryGuidance for the next step, fund the wallet, and create the token again.

event: message
data: {"type":"requirement-expired","requirementId":"...","kind":"gas","finalShortfallWei":"4200000000000000","recoveryGuidance":"Funding window elapsed. Retry the deployment after funding the wallet."}

Match each requirement-resolved or requirement-expired event to its earlier requirement-required event by requirementId. A single deploy can pause more than once, because the contract deploy and the price feed value submission fund different signer wallets. Read the role field on each pause to know which wallet to fund, and keep listening after a resolution rather than treating it as terminal. Only a complete or error event ends the stream.

Terminal events and failures

A complete event ends the stream. When success is true, the token exists and the creation workflow finished every applicable phase. When success is false, the event carries failedSteps, where each step reports its id, label, and a typed wireError payload that matches the structured error a failed deployment returns over REST.

{
  "type": "complete",
  "success": false,
  "failedSteps": [
    {
      "id": "granting-permissions",
      "label": "Granting Permissions",
      "wireError": {
        "dalpCode": "DALP-XXXX",
        "retryable": false,
        "suggestedAction": "A human-readable next step for the failing phase."
      }
    }
  ]
}

Read dalpCode, retryable, and suggestedAction from each failed step to decide whether to retry. A structured deployment failure returns the same public fields over REST.

An error event ends the stream when the stream itself cannot read progress, rather than when a deployment phase fails. It carries the public Platform API error envelope so a client reads the same dalpCode, retryable, and suggestedAction fields it reads elsewhere.

Error codeWhen it happensWhat to do
DALP-0020The stream could not read the latest workflow status from the Workflow Engine.Reconnect to the stream, or poll the create request's status URL after a short backoff.
DALP-0021The creation workflow ended with a Workflow Engine terminal error before the stream read a typed tree.Read the create request's status, then create the token again only after correcting the failure.

For the structured failure shape on each failed step and the retry fields it exposes, see Error handling.

Choose the stream or the status URL

Both surfaces report the same creation outcome. Pick the one that fits how your client follows the work.

GoalWhat to use
Show live deployment phases in a session-backed consoleOpen GET /api/v2/tokens/create/{transactionId}/stream.
Track creation from a scheduled or server-side clientPoll the create request's statusUrl from Token lifecycle.
Confirm the final result after a stream closesRead the create request's status URL once.

On this page