Skip to main content
All requests require an API key via the X-API-Key header. This endpoint requires a secret key (sk_live_) even though it is a read, because the response contains a signed payload. Call it from your backend. See Authentication for details.
The organization attached to the API key must have the organization:incentivize:streams permission. If your organization does not have that permission enabled, contact the Turtle team to request it.

Overview

GET /v2/streams/{id}/admin-operations/active returns the admin operation currently blocking a token-based stream, and until when it blocks it. An admin operation is a backend-signed change to a stream’s funds that the stream admin submits to the StreamFactory. There are two kinds today:
  • a withdrawal, signed by Withdraw Funds
  • a budget increase, made outside the Earn API
A stream accepts only one admin operation at a time, so the response tells you whether the stream can take a new one. Use this endpoint to:
  • Recover a lost payload. If your client lost the txParams of a signed operation (a closed browser, a dismissed wallet prompt), the endpoint returns the same payload. Nothing is re-signed, so it grants nothing the original signature did not.
  • Check whether the operation executed. Once confirmedTxHash is set, the transaction landed on-chain and must not be submitted again.
  • Know when the stream frees up. blockingUntil is when the stream accepts a new withdrawal or budget increase.

Endpoint

Parameters

Path Parameters
uuid
required
Stream identifier, as returned in id by Get Streams. The stream must be token-based and belong to the organization attached to the API key.

Response Examples

Response Fields

ActiveAdminOperation | null
required
The admin operation blocking the stream. null when the stream accepts a new withdrawal or budget increase.

ActiveAdminOperation

string
required
Which StreamFactory function txParams calls, and therefore the shape of txParams.params.params: withdraw (withdrawFunds) or add_funds (addFunds).
object
required
Signed payload of the operation, exactly as it was issued.
integer
required
Chain where the stream lives and where the transaction must be submitted.
string
required
Stream admin wallet. It is the only wallet that can submit the transaction.
object
required
Signed arguments of the StreamFactory call. Exactly one of two shapes, selected by type:
  • withdraw: stream, to, and amount, all present
  • add_funds: stream, netAmount, and feeAmount, all present
The two shapes never mix: a withdraw payload carries no netAmount or feeAmount, and an add_funds payload carries no to or amount.
string
required
Stream contract address. Present for both types.
string
withdraw only. Recipient of the withdrawn tokens.
string
withdraw only. Amount to withdraw in the reward token’s smallest unit.
string
add_funds only. Budget increase in the reward token’s smallest unit.
string
add_funds only. Fee charged on top of netAmount, in the reward token’s smallest unit.
string
required
Unique 32-byte value (hex) that makes the signature single-use.
integer
required
Unix timestamp, in seconds, after which the signature is no longer accepted on-chain. Returned as a JSON number.
string
required
EIP-712 signature bytes serialized as base64 in JSON.
datetime
required
When the stream accepts a new withdrawal or budget increase again. See When the stream frees up.
datetime | null
required
Block time of the transaction that executed the operation. null until it executes.
string | null
required
Hash of the transaction that executed the operation. null until it executes. Once set, do not submit txParams again.

Operation Lifecycle

When the stream frees up

blockingUntil is the earlier of:
  • txParams.params.deadline plus a one-minute tolerance for chain clock skew. After that, the signature can no longer be used.
  • confirmedAt plus the finality window of the stream’s chain. After that, the executed transaction can no longer be reverted by a reorg.
For example, an Ethereum operation signed with a one-hour expiration and executed 20 minutes later frees the stream 15 minutes after execution, well before its deadline.

Resume a Pending Operation

Read the operation from your backend, then let the stream admin wallet submit it according to type. The StreamFactory address for each chain is listed in StreamFactory addresses by chain.
See Broadcast the Withdrawal Transaction for the wallet and chain checks to run before submitting.

Operational Notes

The endpoint returns the payload that was signed when the operation was created: same parameters, same salt, same deadline. Calling it repeatedly never extends the deadline or creates a new signature.
A budget increase made outside the Earn API blocks the stream exactly like a withdrawal does. It shows up here with type: "add_funds", and Withdraw Funds rejects new requests until its blockingUntil.
confirmedAt and confirmedTxHash are set when Turtle detects the executing transaction on-chain. They can lag a few moments behind the transaction receipt your wallet returns.
Point-based streams hold no on-chain funds, so they cannot be withdrawn from or topped up through the StreamFactory. Requesting one returns 400 Bad Request.
This endpoint requires three things at the same time: a valid X-API-Key header, a secret key, and the organization:incentivize:streams permission on the organization attached to that key.

Error Handling

Status Code: 401 Unauthorized
A key that is present but invalid, inactive, or expired returns 401 as well, with "Invalid API key", "API key is inactive", or "API key has expired".Solution: Pass a valid X-API-Key header.
Status Code: 403 Forbidden
Solution: Call this endpoint from your backend with a secret key (sk_live_).
Status Code: 403 Forbidden
Solution: Use an API key associated with an organization that has the organization:incentivize:streams permission.
Status Code: 400 Bad Request
Solution: Only request token-based streams.
Status Code: 404 Not Found
This happens when the id path parameter does not correspond to a stream owned by the organization attached to the API key.
Status Code: 429 Too Many Requests
Usage is metered per key, hourly and monthly. Every response carries the hourly budget in the X-RateLimit-* headers; keys with a monthly limit also get X-Monthly-* headers. A monthly overrun returns "Monthly usage limit exceeded" instead.Solution: Back off until the window resets — hourly limits also return Retry-After — or ask the Turtle team for a higher limit. See Rate limits.
Status Code: 500 Internal Server ErrorSolution: Retry the request and contact Turtle if the issue persists.