Name.al · Albanian Domain Registration

Help Center / api

Rate limits

Our API uses rate limiting to ensure fair usage and stability. Learn how limits work and how to handle them.

How the limit works

OSIR does not sell API tiers. Limits exist only to stop one caller starving the others, and they are deliberately generous for automated clients.

Caller Limit
Anonymous (no credentials) 150 requests/minute per IP
Authenticated (bearer token) 500 requests/minute per account

Budgets refill continuously rather than resetting on a clock, so a burst that reaches the limit recovers within seconds. Health checks are never limited.

Two flows carry their own limits: AI chat relay 150/minute, and account signup 50/day per IP and 3/day per e-mail address.

Rate Limit Headers

Responses carry one header:

x-ratelimit-remaining: 149
Header Description
x-ratelimit-remaining Requests left in your current budget

A 429 additionally carries Retry-After and X-RateLimit-Retry-After, both in seconds.

Read x-ratelimit-remaining on every response and slow down as it approaches zero. X-RateLimit-Limit and X-RateLimit-Reset are not sent, so do not build logic that depends on them.

For automated clients

Availability results are cached briefly, so repeated checks of the same name never reach the registry. Anything that moves money accepts an Idempotency-Key, so retrying after a 429 or a timeout cannot double-charge you.

Handling Rate Limits

Check Headers

const response = await fetch('https://be.osir.com/v1/public/catalog/domains/example.com/availability')
const remaining = response.headers.get('x-ratelimit-remaining')

if (remaining < 10) {
  // Slow down requests
}

Handle 429 Errors

async function fetchWithRetry(url, options, retries = 3) {
  const response = await fetch(url, options)

  if (response.status === 429 && retries > 0) {
    const retryAfter = response.headers.get('Retry-After') || 60
    await sleep(retryAfter * 1000)
    return fetchWithRetry(url, options, retries - 1)
  }

  return response
}

429 Response

When rate limited. Honour the Retry-After header: retrying immediately spends budget you do not have.

{
  "error": "Rate limit exceeded",
  "retryAfterSeconds": 42
}

Best Practices

1. Implement Exponential Backoff

async function backoff(attempt) {
  const delay = Math.min(1000 * Math.pow(2, attempt), 30000)
  await sleep(delay)
}

2. Use Caching

// Cache responses that don't change often
const cache = new Map()
const CACHE_TTL = 60000 // 1 minute

async function getCachedDomains() {
  if (cache.has('domains') && cache.get('domains').expires > Date.now()) {
    return cache.get('domains').data
  }

  const data = await fetchDomains()
  cache.set('domains', { data, expires: Date.now() + CACHE_TTL })
  return data
}

3. Batch Requests

Instead of:

// Bad: 100 requests
for (const domain of domains) {
  await checkDomain(domain)
}

Use:

// Good: 1 request
await checkDomains(domains) // Bulk endpoint

Increasing Limits

Need higher limits?

  1. Upgrade your plan
  2. Contact sales for enterprise pricing
  3. Apply for partner program