Skip to main content

Errors & responses

This page describes the response and error format shared by all Staking API endpoints, and how to handle transactions after you broadcast them. For exact per-endpoint response schemas, always check the Swagger console and the OpenAPI schema.

Success responses

Successful requests return 200 OK (or 201 Created when creating a resource) with a JSON body. Crafting and prepare endpoints return transaction payloads; read endpoints return balance/stake data. Examples are shown throughout each network's Endpoints page and in the Quickstart.

Error format

When a request fails, the API returns a JSON body with a consistent shape:

{
"statusCode": 400,
"message": "Bad Request",
"error": "Bad request error message"
}
FieldDescription
statusCodeHTTP status code, mirrored in the response body.
messageShort HTTP status message (may be null).
errorHuman-readable description of what went wrong.

Common status codes

StatusMeaningTypical cause & fix
400 Bad RequestThe request was rejected.Invalid or missing body fields, malformed address, amount below the network minimum, or an action that is not currently valid (e.g. withdrawing before the unlock period). Check the error message and validate against the OpenAPI schema.
401 UnauthorizedAuthentication failed.Missing, invalid, revoked, or expired X-API-KEY. Verify the key in the dashboard.
404 Not FoundThe resource does not exist.Wrong path, or an identifier (e.g. address, withdrawal ID) that has no matching record.
429 Too Many RequestsRate limit exceeded.You exceeded the per-key or per-IP request rate. Back off and retry; see Rate limits.
5xxServer-side error.Transient upstream/RPC issues. Safe to retry crafting and read calls with backoff (see below).
tip

Some actions are only valid in a specific on-chain state; for example, a Pharos withdraw before the 84-epoch window, or a Solana withdraw before deactivation completes. These return a 400 with an explanatory error; they are not bugs in your request but timing conditions. Use the balance endpoints to check state before crafting.

Retrying safely

The four steps have different retry semantics:

  • Craft, prepare, and read endpoints are stateless and do not move funds. They are safe to retry with exponential backoff on network errors or 5xx responses.
  • Broadcast submits a signed transaction to the blockchain. Do not blindly re-broadcast on a timeout: first check whether the transaction already landed (by its hash, via an explorer or your RPC). Re-broadcasting the same signed transaction is generally rejected by the network as a duplicate, but you should confirm status rather than assume.

There are no idempotency keys; idempotency comes from the blockchain itself: a given signed transaction can only be included once.

After broadcasting

broadcast returns a transaction identifier (tx_hash). Broadcasting means the transaction was submitted, not necessarily finalized. To confirm the result:

  1. Take the returned hash.
  2. Poll its status on the target network (via a public explorer or your own RPC node).
  3. Treat the operation as complete only once the network reports it confirmed/finalized.

Staking state changes (activation, unbonding, exit queues, withdrawal windows) then follow each network's own timing; see the relevant network section and the comparison in How it works.

Response signature verification (optional)

Every response also includes an x-signature header you can use to verify the payload's integrity and authenticity against Stakely's public RSA key. This is optional but recommended for high-assurance integrations; see Authentication → Response signature verification.

Service health

A public, no-auth health check is available for monitoring and uptime probes:

curl "https://staking-api.stakely.io/api/v1/health"

It returns 200 OK with a status object when the API and its database are healthy, and 503 Service Unavailable otherwise. No X-API-KEY is required, so it is safe to poll from external monitors.

Rate limits

The API rate-limits requests at two levels, chosen automatically per request depending on whether it carries an X-API-KEY header:

RequestLimitCounted by
Authenticated (X-API-KEY present)200 requests per minutePer API key (each key has its own independent quota)
Unauthenticated (public endpoints, no key)60 requests per minutePer source IP

If the key is present, the per-key quota applies; otherwise the request falls back to the per-IP quota. No request goes unlimited. The window is a sliding 1-minute window with no extra burst allowance, so the allowed peak equals the average (200 and 60 respectively).

Requests over the limit receive 429 Too Many Requests. Design clients to back off and retry rather than hammer the API. The per-IP count uses the real client IP resolved via Cloudflare (CF-Connecting-IP), not the proxy address.

If your integration needs sustained higher throughput, contact [email protected] to confirm the limits that apply to your account.

API versioning

The API is versioned in the URL path: all endpoints live under /api/v1. The OpenAPI schema is the source of truth for the current surface; any breaking changes would be introduced under a new version path so existing integrations keep working.