Skip to main content
Every endpoint returns errors in one shape, and the SDK maps each status onto a typed class you can branch on.

The Error Envelope

Non-2xx responses always return this object:
error is a human-readable message, code is the stable machine-readable identifier to branch on, and details carries field-level messages on validation failures and is null otherwise.

API Error Codes

A 404 from GET /v1/claims/{campaignId}/{address} has three causes, and two of them are ordinary: the address has no position in that campaign, or no published merkle root covers its rewards yet. Neither is a failure. Catch it and render an accruing state rather than an error.The third is different: the endpoint also 404s once the claim window has closed, even for a user who has a published, unclaimed leaf. Rendering “rewards accruing” there is wrong and permanent. Check campaign.endTime plus the claim window before choosing the copy.
If you are checking many campaigns at once, claims.statuses avoids the problem entirely: campaigns without a published root report claimable: 0n instead of erroring. The same applies to referrals.proof: it 404s until the campaign has finalized and its referral root is published, which is the normal state for every live campaign.

Referral Bind Codes

POST /v1/referrals/bind (tbi.referrals.bind and submitBind) has its own rejection codes. The SDK raises them as TbiApiError, so branch on error.code. Re-submitting the exact same bind is not an error: it resolves with created: false. None of these codes should block a deposit. See Add Referrals for a worked handler.
The error-code set grows additively. Two more bind codes exist that the SDK never triggers: REFERRER_NOT_FOUND (404) when a raw REST bind sends a referrerUsername no account has claimed, and INVALID_SESSION (401) for Rabbithole’s own session-authenticated binds. Treat any code you do not recognise as a generic error.

SDK Error Classes

All SDK errors extend TbiError and carry a code. Branch on the class, not the message:
Wallet write failures are not wrapped. A user rejecting the transaction, an out-of-gas error, or a contract revert propagates straight from your wallet client, so you can surface the wallet’s own message. See Contracts for the revert selectors.

What Retries Automatically

The SDK retries network errors, HTTP 429, and HTTP 5xx with exponential backoff of baseDelayMs * 2^(attempt - 1), defaulting to 3 total attempts and a 200 ms base. Other 4xx responses and aborted requests are never retried, because retrying them cannot succeed.
Pass an AbortSignal on any read method to cancel in-flight requests. A cancelled request is never retried:

Contract Reverts

Once a claim transaction is submitted, failures come from the TBI Manager contract rather than the API.

Revert Selectors

InvalidProof, NothingToClaim, ClaimExpired, the referral claim errors, and the cause of each.

Keep Exploring

Data Conventions

Wire formats, pagination, caching, and rate limits.

Claim Rewards

The claim flow end to end, including simulating before you sign.