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}/streamPass 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.cookiesA 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 type | Payload fields | Client handling |
|---|---|---|
tree | nodes | Replace the local phase tree with the received tree. |
update | nodeId, status, optional error | Patch the matching phase in the local tree. |
requirement-required | requirementId, kind, payload | The deploy paused and needs a manual step, such as funding the creator wallet. Show the requirement and keep listening. |
requirement-resolved | requirementId, kind, optional resolution | The requirement cleared and the deploy resumed. Clear the requirement view and keep listening. |
requirement-expired | requirementId, kind, finalShortfallWei, recoveryGuidance | The requirement was not met in time. Read recoveryGuidance and expect a terminal failure. |
complete | success, optional failedSteps | Stop listening. When success is false, read failedSteps for the failure. |
error | message, error | Stop 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 field | Meaning |
|---|---|
role | Which 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. |
chainId | The numeric chain id the deploy runs on. |
chainName | The human-readable network name. |
address | The wallet address to fund. |
tokenSymbol | The gas token symbol for that network. |
shortfallWei | The amount still missing, in wei, as a decimal string. Send at least this much. |
recommendedTotalWei | The 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 code | When it happens | What to do |
|---|---|---|
DALP-0020 | The 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-0021 | The 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.
| Goal | What to use |
|---|---|
| Show live deployment phases in a session-backed console | Open GET /api/v2/tokens/create/{transactionId}/stream. |
| Track creation from a scheduled or server-side client | Poll the create request's statusUrl from Token lifecycle. |
| Confirm the final result after a stream closes | Read the create request's status URL once. |
Related
- Token lifecycle covers the create request, prerequisites, idempotency rules, and the polling status URL.
- Create an asset covers the same funding pause from the Asset Designer deploy screen.
- Organisation deployment API documents the parallel deployment stream for organisation setup.
- Error handling describes the structured deployment-failure shape and retry fields.
- Request headers covers identity, executor, and network headers for create requests.
- Getting started with API integration
Corporate actions
Named catalog for cash dividends, bond coupons, bonus issues, rights issues, capital decreases, splits, and spin-offs.
Token holders and transfer operations API
Query token holders, inspect balances, execute transfers, and understand the controls around standard, allowance-based, forced, and pre-approved transfer workflows.