All requests require an API key via the
X-API-Key header.
See Authentication for details.Overview
POST /v1/streams/ creates a new incentive stream owned by the organization attached to the API key.
There are two creation flows:
- Token-based stream: the API validates the request, stores the pending stream, and returns
txParamswith the backend-signed authorization that your wallet must submit on-chain to the correspondingStreamFactory. - Point-based stream: the API creates the stream immediately and returns
txParams: null.
rewardTokenId, you do not need to create or reference a point.
A stream can use both
rewardTokenId and targetTokenId on the same chain. The difference is support scope, not a requirement to split them across networks. Reward-token selection is currently supported only for stream creation on 5 networks: Ethereum, Base, Avalanche, BSC, and Sepolia. targetTokenId supports a broader set of chains through Get Tokens, where the lookup uses the decimal EVM chainId.Supported Stream Types
| Type | Strategy | Required behavior |
|---|---|---|
1 | Fixed Rate | totalAmount required for token-based streams |
2 | Fixed APR | rewardTokenId and totalAmount required |
3 | Variable Rate | totalAmount must be omitted |
Create a Token-Based Stream
If you are creating a token-based stream, use Get Tokens to list the supported reward-token UUIDs (
rewardTokenId) for the selected chain, or to discover supported target tokens used in strategy customArgs (for example, targetTokenId). For rewardTokenId, choose a token where isAllowedRewardToken is true.Create a Point-Based Stream
If you are creating a point-based stream and do not yet have a point asset for your organization, use Create Point first. You can list existing organization points with Get Points.
Request Body
Admin EVM address for token-based streams. Must be omitted for point-based streams.
Stream type. Supported values are
1, 2, and 3.Reward token UUID (use the token
id from Get Tokens) for token-based streams. Exactly one of rewardTokenId or pointId must be provided. Choose a token where isAllowedRewardToken is true. Reward-token selection for stream creation is currently limited to Ethereum, Base, Avalanche, BSC, and Sepolia; rewardTokenId will be resolved by the server into the token address and chain used for on-chain creation.Point identifier for point-based streams only. Exactly one of
rewardTokenId or pointId must be provided. See Get Points for the Point schema and examples.Total rewards in base units. Required for token-based fixed-rate and fixed-APR streams. Must be omitted for variable-rate streams. For token-based streams, this is the amount that will be sent to the smart contract onchain when the wallet submits the returned
txParams, so the wallet must already hold the required balance.UTC stream start timestamp. Must align to a 15-minute boundary.
Optional UTC stream end timestamp. If provided, it must be at least one hour after
startTimestamp and aligned to a 15-minute boundary. For token-based variable-rate streams, it is required.Strategy-specific configuration object. See customArgs by Type for details.
Optional adapter configuration array. Each adapter entry must include
type and params.customArgs by Type
Fixed Rate (type = 1)
targetTokenId: supported target token used as the tracked balance source. Resolve it through Get Tokens using the decimal EVMchainIdfor the target-token network.tokensPerUSD: positive reward-emission coefficient in base units. Specifies the daily number of token/point wei units to grant for every 1,000 USD of provisioned TVL.
Fixed APR (type = 2)
targetTokenId: supported target token used as the tracked balance source. Resolve it through Get Tokens using the decimal EVMchainIdfor the target-token network.apr: positive decimal APR value.
Variable Rate (type = 3)
targetTokenId: supported target token used as the tracked balance source. Resolve it through Get Tokens using the decimal EVMchainIdfor the target-token network.tokensPerDay: positive per-day reward budget in base units.
Response Examples
Token-based response
Point-based response
Response Fields
Status message describing the creation path used.
On-chain creation payload for token-based streams. Submit it to the corresponding
StreamFactory on txParams.chainId. null for point-based streams.Chain where the stream-factory transaction must be submitted.
Wallet expected to submit the transaction.
16-byte stream ID encoded as a byte array for the stream factory call.
Reward token contract address.
Streamed amount in decimal-string form to preserve precision.
Creation fee amount in decimal-string form.
Unix timestamp deadline for the signed payload.
EIP-712 signature bytes serialized as base64 in JSON.
Persisted stream record created by the request. It uses the same public stream schema returned by Get Streams.
Persisted adapter configuration array. Each item contains a
type string and a params object.Reward-token metadata for token-based streams. This uses the same token shape returned by Get Tokens.
Broadcast the Token-Based Transaction
For token-based streams, the backend does not return a fully serialized raw transaction. Instead, it returns a signed authorization payload intxParams that your wallet must use to call createStream on the StreamFactory for the target chain.
The wallet that sends the transaction must:
- match
txParams.sender - be connected to
txParams.chainId - approve the
StreamFactoryto transfer the reward token amount needed forNetTotalAmount + FeeAmount
StreamFactory addresses by chain
chainId | Network | StreamFactory |
|---|---|---|
1 | Ethereum | 0xf44399a74ee5ddef7fa3d064cf66b011ee4a6cae |
56 | BSC | 0x298d2967588b5c93a137ce1a05d0b8cfffb3c120 |
43114 | Avalanche | 0x4559605e3003fda8c059e14af4f16ba9a004335a |
8453 | Base | 0x4559605e3003fda8c059e14af4f16ba9a004335a |
11155111 | Sepolia | 0xdfdff939d728585ce8a2cf2d4166f043d917d8d2 |
TypeScript example
Operational Notes
Token-based streams are not broadcast automatically
Token-based streams are not broadcast automatically
The endpoint does not submit the transaction to the chain. It returns the payload required to finalize creation through the
StreamFactory contract. See Broadcast the Token-Based Transaction for the chain addresses and a TypeScript example. When the wallet submits that transaction, the configured totalAmount is part of the on-chain flow, so the wallet must already hold those funds.A valid API key alone is not enough
A valid API key alone is not enough
This endpoint requires two things at the same time: a valid
X-API-Key header and the organization:incentivize:streams:create permission on the organization attached to that key. If the organization has not been granted that permission, stream creation will be rejected.Point-based streams are created immediately
Point-based streams are created immediately
Point-based streams do not require an on-chain deployment step, so
txParams is null and the stream is created directly in Turtle’s backend. In that case, the returned stream is already confirmed.Token-based streams are returned in pending state first
Token-based streams are returned in pending state first
For token-based streams, the response already includes a persisted
stream object, but it is still pending until the wallet broadcasts the returned txParams to the StreamFactory. Until that happens, fields such as stream.contractAddress and stream.creationConfirmedAt can remain null.Timestamp alignment is strict
Timestamp alignment is strict
startTimestamp and endTimestamp must be aligned to 15-minute intervals such as 00:00, 00:15, 00:30, or 00:45 UTC.Exactly one reward source must be provided
Exactly one reward source must be provided
rewardToken and pointId are mutually exclusive. You must specify exactly one of them:rewardTokenIdfor token-based streamspointIdfor point-based streams
Points are not part of token-based stream creation
Points are not part of token-based stream creation
If you are creating a stream with
rewardTokenId, you do not need a point and must not send pointId. Points only apply when the reward source is organization-defined points.Error Handling
Missing or invalid API key
Missing or invalid API key
Status Code: 401 UnauthorizedSolution: Pass a valid
X-API-Key header.Permission denied
Permission denied
Status Code: 403 ForbiddenSolution: Use an API key associated with an organization that has the
organization:incentivize:streams:create permission.Invalid payload
Invalid payload
Status Code: 400 Bad RequestCommon causes:
- unsupported
type - invalid
customArgsfor the chosen type - timestamps not aligned to 15-minute boundaries
totalAmountpresent for variable-rate streamswalletAddressorrewardTokenIdmissing for token-based streams
Unexpected internal error
Unexpected internal error
Status Code: 500 Internal Server ErrorSolution: Retry the request and contact Turtle if the issue persists.

