Errors and limits
The refusals every keyed call shares, in the interface description's own words: one row per status code, the calls that answer it, and the count each scope allows per key in one fixed minute. The one error shape a refusal carries stands on the API reference.
The status codes
Every refusal the document's calls answer, one row per status code. Each sentence is the document's own, and the calls named under it answer with exactly that sentence.
| Status | What it answers |
|---|---|
| 400 | The query could not be read. Answered by The request body could not be read. Answered by The reference is missing or is not an opaque id. Answered by |
| 401 | The key is missing, malformed, unknown, revoked or expired. Answered by |
| 403 | The key does not carry the scope, or the wallets name no chain the distributor serves. The call is also refused with 403, nothing read, when the distributor is paused, suspended or closed, when the key is paused, or when the key presents from an origin it does not allow. Answered by The key does not carry the scope. The call is also refused with 403, nothing read, when the distributor is paused, suspended or closed, when the key is paused, or when the key presents from an origin it does not allow. Answered by The key does not carry the scope, or the challenge itself was refused: the venue is paused or not a self-custody venue, the benefit is not a claimable offer, or a wallet sits on a chain the venue does not serve. The call is also refused with 403, nothing read, when the distributor is paused, suspended or closed, when the key is paused, or when the key presents from an origin it does not allow. Answered by The key does not carry the scope, or the claim itself was refused: the challenge was never verified, was issued for another distributor or another benefit, or the holder's own world refused the claim, and the attested subject's statement the same - unsigned or unverifiable, expired, naming an instrument the distributor does not list or the registry no longer keeps active, naming another tenant, or for a benefit the account's holder already claimed once. The call is also refused with 403, nothing read, when the distributor is paused, suspended or closed, when the key is paused, or when the key presents from an origin it does not allow. Answered by The key does not carry the scope, or the fulfilment was already confirmed: the confirm that stands is the one that landed first. The call is also refused with 403, nothing read, when the distributor is paused, suspended or closed, when the key is paused, or when the key presents from an origin it does not allow. Answered by The key does not carry the scope, or the return address is not one the distributor's profile allows. The call is also refused with 403, nothing read, when the distributor is paused, suspended or closed, when the key is paused, or when the key presents from an origin it does not allow. Answered by |
| 404 | No claim answers this id under this distributor's key: an unknown id, or one another distributor's key recorded. The answer is the same for both, so no claim id can be probed. Answered by No fulfilment answers this id under this distributor's key: an unknown id, or one another distributor's key recorded. The answer is the same for both, so no fulfilment id can be probed. Answered by No Connect session answers this id under this distributor's key: an unknown id, a malformed id, or one another distributor's key created. The answer is the same for both, so no session id can be probed. Answered by No standing link answers this reference under this distributor's key. Nothing was read. Answered by |
| 409 | The claim the id names stands rejected or taken back, so it carries no redemption link to reissue. Answered by |
| 429 | The key made too many calls this minute, or the platform has used today's live wallet reads; the Retry-After header names the seconds until the next window opens, or until the reads open again. Nothing was read. Answered by The key made too many calls this minute. The Retry-After header names the seconds until the next window opens. Nothing was read. Answered by |
| 500 | The read failed. Nothing was changed. Answered by The redemption link was not reissued, so the previous link still stands. Nothing was changed. Answered by The challenge was not issued, so nothing is ready to sign. Nothing was changed. Answered by The claim was not recorded, so no benefit was claimed. Nothing was changed. Answered by The fulfilment was not confirmed, so the credit still waits. Nothing was changed. Answered by The Connect session was not created, so no hosted page was started. Nothing was changed. Answered by The person's link was not ended, so the person stays linked. Nothing was changed. Answered by |
| 503 | The data source this read needs is not live yet, or the owners' blockchain switch does not allow the read, so the read is refused. Nothing was read. Answered by The data source this read needs is not live yet, so the read is refused. Nothing was read. Answered by |
The limits
Once the key a call presents stands, the call is counted, per key and per scope, in one fixed window of 60 seconds that starts on the minute. A call past the scope's own count is refused without being counted: the refusal answers the one error shape the Errors section carries, and its Retry-After header names the seconds to wait until the next window opens.
- eligibility.read
- At most 120 calls per key and scope in the window.
- availability.read
- At most 600 calls per key and scope in the window.
- claims.write
- At most 60 calls per key and scope in the window.
- connect.write
- At most 60 calls per key and scope in the window.
- connect.read
- At most 60 calls per key and scope in the window.
- claims.read
- At most 60 calls per key and scope in the window.
- How long an answer stands
- Every other read's answer is private to the distributor that asked and may stand for 60 seconds. The GET /v1/connect/sessions/{id} and GET /v1/connect/outcomes reads are never held.
A call past its scope's count answers the 429 row above: nothing was read, and the Retry-After header names when the next window opens.
When a call is limited
A limited call answers the status line, the Retry-After header and the error body below, with the interface description's own sentence for the refusal most calls share.
A refused limit or cursor answers in that same error shape. The Pagination page says what each one carries and how to walk past one page.
HTTP/1.1 429 Too Many Requests
Retry-After: 23
{
"message": "The key made too many calls this minute. The Retry-After header names the seconds until the next window opens. Nothing was read.",
"code": "rate_limited",
"requestId": "req_01K4V9QG000000000000000001"
}The loop reads that header, waits the seconds it names and tries the same call again at most three times. The wait is capped at one hour, the longest wait the SDK itself holds, so a header naming a day never freezes the caller for a day.
async function callWithWait(url, options) {
for (let attempt = 0; attempt < 3; attempt += 1) {
const response = await fetch(url, options);
if (response.status !== 429) return response;
const seconds = Math.min(3600, Math.max(1, Number(response.headers.get("Retry-After")) || 1));
if (attempt < 2) {
await new Promise((resolve) => setTimeout(resolve, seconds * 1000));
}
}
throw new Error("the call was limited after three tries");
}When an element refuses
An element that refuses, whether a value it cannot draw or a read it cannot make, keeps its last good paint and throws nothing into your page: the element sets data-yutai-state="refused" on itself and fires one yutai-error event that bubbles and is composed, so a listener on your document hears it from inside the element's shadow root. The attribute comes off the next time the element draws, except a refusal a Connect press told, which stands until the next press.
detail.tag- The tag of the element that refused, like yutai-tier-badge, so the page can tell which one it was.
detail.sentence- The plain sentence saying what to fix, written for the page's developer.
document.addEventListener("yutai-error", (event) => {
console.warn(event.detail.tag, event.detail.sentence);
});
// The last good paint stays, and the attribute stands until the element draws again.
const refused = document.querySelectorAll('[data-yutai-state="refused"]');Each element page lists the sentences its own element tells: the credential card, the benefits list, the benefits module and the tier badge. A page built with React hears the same refusals through the wrapper's onError prop.
The status word
The status call needs no key. It answers one word for how the service stands, then one row for every data domain, each carrying the sentence for its SIMULATED, SANDBOX or LIVE mode, so no public read stands without its flag.
ok- The service answers: every check behind the status read passed.
degraded- The service answers only partly: part of it is unavailable.
down- A check failed, so the answer names no data domains at all; the word stands for up to thirty seconds, so a service that has recovered can answer down briefly.
SIMULATED- This is simulated sample data for trying Yutai, not real records.
SANDBOX- This data comes from a provider's test system, not real records.
LIVE- This data is live, read from real records.
Check the API status to read the answer itself, with the fields it carries.