Rate limits and maintenance

API keys have hourly and per-second request limits. Platform access gates can independently restrict OTP authentication and KYC-gated execution.

Check maintenance status#

GET /v1/maintenance is public (no API key).

curl -sS https://api-stg.vudy.app/v1/maintenance
const { data } = await fetch("https://api-stg.vudy.app/v1/maintenance").then(
	(r) => r.json(),
);
// data.status: "ok" | "limited" | "maintenance"
StatusMeaning and integrator action
okOTP and KYC access gates are open; proceed normally
limitedOTP is open but the KYC gate is closed; defer KYC-gated operations
maintenanceOTP is closed; defer OTP send/verify and show an unavailable state

maintenance describes the OTP gate and does not guarantee the state of every other operation. When a route’s required gate is closed, that route returns 503 with a standard error envelope. For OTP, retry once status is no longer maintenance. For a KYC-gated operation, retry after status returns to ok.

Rate limits#

Limits are assigned per API key: an hourly budget and a token-refilled per-second burst budget. Read the response headers instead of hard-coding limits.

API-key-authenticated responses normally expose:

HeaderMeaning
RateLimit-LimitActive limit represented by the response
RateLimit-RemainingRemaining requests for that window
RateLimit-ResetSeconds until reset, not a timestamp
RateLimit-PolicyBoth policies in <limit>;w=<seconds> form
Retry-AfterWhole seconds to wait when the current request is blocked

On exceed:

  • HTTP 429
  • SERVER_VALIDATION_API_AUTH_12 for the hourly limit or SERVER_VALIDATION_API_AUTH_19 for the burst limit
  • RateLimit-*, RateLimit-Policy, and Retry-After headers
const res = await fetch("https://api-stg.vudy.app/v1/config/chains", {
	headers: { "x-api-key": process.env.VUDY_API_KEY },
});

if (res.status === 429) {
	const retryAfter = Number(res.headers.get("Retry-After") || "1");
	await new Promise((r) => setTimeout(r, retryAfter * 1000));
	// Retry only when this operation is safe to repeat.
}

Use exponential backoff for repeated 429 responses and cap retry attempts. A successful response’s reset value describes the hourly window; on a blocked response, the limit/reset headers describe the window that blocked the request.

Do not assume a mutation is idempotent unless its endpoint documentation says so. See Responses and errors and Troubleshooting.