Skip to main content

Generate emergency claim calldata – Earn API

Updated on
Jul 31, 2026

Overview​

Escape hatch for a stalled deposit bridge leg: fetches the finalized Circle attestation and returns one ready-to-sign emergencyClaimBridge transaction on the destination chain. Minted USDC goes directly to the burn-time beneficiary's wallet, bypassing the destination vault deposit. The matching intent (kind emergency_claim) is written server-side. No auth.

Eligibility (each failure is a 400 invalid_state): the transfer must be a deposit leg, not already confirmed or user_claimed, at least 30 minutes old, and its recorded beneficiary must be the strategy owner. If Circle has not finalized the attestation, the response is a 409 attestation_pending; poll on that status code.

approvalsNeeded is always []. expiresAt is nominal: the claim stays valid until the message nonce is consumed on the destination chain. A null gasHint with estimation_failed can mean the nonce was already consumed (the transfer completed normally); the on-chain result is authoritative.

Endpoint​

POST https://earn-api.quicknode.dev/functions/v1/api/v1/strategies/{id}/calldata/claim

Authorization​

Include the published apikey header. This endpoint is public and does not require a SIWE signature.

Rate limits​

This operation belongs to the calldata rate-limit bucket. It allows 10 requests per 60 seconds, keyed by strategy+ip. A coarser limit of approximately 30 requests per 60 seconds also applies per IP across deposit, withdrawal, and claim calldata requests.

Parameters​

ParameterLocationTypeRequiredDescription
idpathstringYesStrategy UUID.

Request body​

Emergency claim request body. Public (no SIWE). Unlike deposit/withdraw an empty body is NOT valid: the route cannot pick a stalled transfer for the caller.

FieldTypeRequiredDescription
transferIdstringYesThe stalled transfer's `cctp_transfers` row id (find it via `GET /v1/strategies/{id}/bridges`).

Example request​

curl --request POST \
--url 'https://earn-api.quicknode.dev/functions/v1/api/v1/strategies/b7c1e2d3-0000-4000-8000-000000000001/calldata/claim' \
--header 'Accept: application/json' \
--header 'apikey: <EARN_PUBLIC_API_KEY>' \
--header 'Content-Type: application/json' \
--data '{
"transferId": "9a8b7c6d-0000-4000-8000-000000000123"
}'

Response​

FieldTypeRequiredDescription
kindstring (claim)YesIdentifies the response as an emergency claim calldata plan.
transactionsarray<object>YesExactly one `emergencyClaimBridge` transaction, on the transfer's DESTINATION chain (transaction kind `emergency_claim`).
approvalsNeededarray<object>YesAlways empty (`emergencyClaimBridge` pulls no tokens from the sender).
expiresAtstringYesAdvisory only — a finalized attestation stays valid until the nonce is consumed on the destination chain.
transactions[].chainIdintegerYesDestination chain on which to submit the claim.
transactions[].tostringYesQuicknode Earn proxy on the destination chain.
transactions[].datastringYesEmergency-claim calldata. Submit it verbatim.
transactions[].valuestringYesNative-token value. Always `"0"`.
transactions[].intentIdstringYesIntent UUID used to track the claim.
transactions[].kindstring (emergency_claim)YesTransaction intent kind.
transactions[].descriptionstringYesHuman-readable claim summary.
transactions[].gasHintstring | nullYesRecommended gas limit, or `null` when estimation failed.
transactions[].gasHintReasonstringNo`estimation_failed` when `gasHint` is `null`.

Example response​

{
"kind": "claim",
"transactions": [
{
"chainId": 42161,
"to": "0x48b415841165304f7EfaA7D5dD5FC65cc7B4bd8e",
"data": "0x0f2b1a3c0000000000000000000000000000000000000000000000000000000000000040",
"value": "0",
"intentId": "7f3a1c2b-0000-4000-8000-000000000abc",
"kind": "emergency_claim",
"description": "Claim bridged USDC on chain 42161 directly to your wallet, bypassing the relayer and the destination vault deposit",
"gasHint": "220000"
}
],
"approvalsNeeded": [],
"expiresAt": "2026-07-07T19:00:00.000Z"
}

HTTP responses​

StatusDescription
200One emergency-claim transaction on the destination chain.
400A malformed JSON body or `transferId` (`invalid_request`), or the transfer is not claimable (`invalid_state`: already terminal, not deposit-shaped, not 30 minutes old yet, or the beneficiary does not match the strategy owner).
404Strategy not found (`not_found`), or no such CCTP transfer for this strategy (`transfer_not_found`; also returned when the transfer belongs to another strategy).
409Attestation not finalized yet (`attestation_pending`). Retry after `Retry-After` seconds.
429Rate limit exceeded. `Retry-After` (seconds) tells you when to retry. Reads, feedback, and push writes are keyed per IP; create/update/delete are keyed per wallet+IP; deposit/withdraw/claim calldata is keyed per strategy+IP.
500Internal error (including a failed intent write), or `unsupported_chain_pair` when the transfer's chain pair has no CCTP route configured.
OpenAPI source

This page is based on operation claimCalldata in the Earn OpenAPI 3.1 specification.