asicapidocs

Rate limits and ASIC availability

asicapi rate limits per API key, the RateLimit headers, how to handle 429 and 503 responses with backoff, ASIC maintenance windows, and caching guidance.

asicapi limits each API key to 600 requests per minute and 20 requests in flight at once. The limits protect both the API and ASIC's register, which every live request ultimately queries. Responses carry standard RateLimit-* headers so a client can pace itself, and a breach returns 429 with a Retry-After header rather than silently queuing. ASIC's own availability is surfaced separately as 503 asic_unavailable, so you can tell a limit you can control apart from an outage you cannot.

Limits

LimitValueScope
Requests per minute600Per API key, sliding window
Concurrent requests20Per API key, requests with a response not yet sent
Batch document lookup10 document numbersPer GET /v1/documents?numbers[]= request
Batch person extract100 peoplePer POST /v1/people/extracts request
Offline searches20 per dayPer account

Test keys share the same limits as live keys so that load behaviour in development matches production. Higher limits are available on request for accounts with sustained volume.

Rate limit headers

Every response includes three headers.

HeaderExampleMeaning
RateLimit-Limit600Requests allowed in the current window
RateLimit-Remaining597Requests left in the current window
RateLimit-Reset42Seconds until the window resets and RateLimit-Remaining returns to the limit

When a request is rejected for exceeding a limit the response also carries Retry-After with the number of seconds to wait.

Response headers
HTTP/1.1 429 Too Many Requests
Content-Type: application/json; charset=utf-8
RateLimit-Limit: 600
RateLimit-Remaining: 0
RateLimit-Reset: 17
Retry-After: 17
X-Request-Id: req_01J8ZKG6H1J5K9
Response (429 Too Many Requests)
{
  "error": {
    "type": "rate_limit_error",
    "code": "rate_limited",
    "message": "This key has exceeded 600 requests per minute. Retry after 17 seconds.",
    "param": null,
    "asicCode": null,
    "requestId": "req_01J8ZKG6H1J5K9",
    "docUrl": "https://asicapi.dev/docs/errors#rate_limited"
  }
}

A concurrency breach returns the same code with a message naming the concurrency limit and a Retry-After of 1.

Handling 429 with backoff

Treat 429 as a signal, not an error to surface to users. A simple and safe pattern:

  1. Read Retry-After and sleep for that many seconds. If the header is missing, start at one second.
  2. Retry the same request.
  3. On repeated 429, double the wait each time up to 60 seconds and add a small random jitter so that many workers do not retry in lockstep.
  4. Give up after a bounded number of attempts and record the requestId.
TypeScript
async function withRetry<T>(fn: () => Promise<Response>, attempts = 6): Promise<Response> {
  let delay = 1000;
  for (let i = 0; i < attempts; i++) {
    const res = await fn();
    if (res.status !== 429 && res.status !== 503) return res;
    const retryAfter = Number(res.headers.get('Retry-After'));
    const wait = retryAfter > 0 ? retryAfter * 1000 : delay;
    await new Promise((r) => setTimeout(r, wait + Math.random() * 250));
    delay = Math.min(delay * 2, 60_000);
  }
  throw new Error('asicapi: retries exhausted');
}

Because a 429 is rejected before anything is sent to ASIC, a rate-limited request never incurs a statutory fee. Retrying it is safe and free.

Concurrency

Requests to ASIC's register are synchronous, and a historical company extract for a large company can take several seconds. Keep at most 20 requests in flight per key. If you run a pool of workers, size it at or below 20, or split traffic across keys per service. Requests over the concurrency limit are rejected immediately rather than queued, so a client that ignores the limit will see a burst of 429s instead of slower responses.

Asynchronous products (document image orders, charges extract orders, offline searches) count only for the initial POST. Polling GET /v1/orders/{id} counts against the per-minute limit like any other request, so poll no more often than every few seconds, or use webhooks and avoid polling altogether.

ASIC availability

asicapi queries ASIC's register in real time. When ASIC's database is unavailable the request cannot be served and asicapi returns 503 with code asic_unavailable. This is ASIC's own "database not available, try later" condition, not a fault in your request.

Response (503 Service Unavailable)
{
  "error": {
    "type": "asic_unavailable_error",
    "code": "asic_unavailable",
    "message": "ASIC's database is not available. This is usually a scheduled maintenance window; retry after 300 seconds.",
    "param": null,
    "asicCode": "ZZ51",
    "requestId": "req_01J8ZKH7J2K6L0",
    "docUrl": "https://asicapi.dev/docs/errors#asic_unavailable"
  }
}

Maintenance windows

ASIC takes its public information systems offline for maintenance, most often overnight on weekends (Australian Eastern time) and occasionally for longer scheduled releases announced in advance. During a window every product that reads from the register returns asic_unavailable. Free platform endpoints (identifier validation, code tables, form schedule, GET /v1/orders) keep working because they do not touch ASIC.

Handle 503 the same way as 429: honour Retry-After (asicapi sets it to 300 seconds during a known window), back off exponentially, and do not surface the condition to end users as a failure of their input. The current status of ASIC connectivity is published at https://status.asicapi.dev, and a 503 never incurs a fee.

A distinct 502 asic_application_error means ASIC accepted the request but its application failed while processing it. Retry once; if it recurs the record itself may be the problem, so contact support with the requestId.

Caching guidance

ASIC data changes when a company lodges a form, so sensible caching reduces both latency and statutory fees.

DataChanges whenSuggested approach
Company identity and status (GET /v1/companies/{id})A name change, status change or address change is processedFree to fetch; cache for hours and refresh on demand
Current company extract (office holders, addresses, share capital, members)A Form 484 or similar is processed. Most companies lodge a handful of forms a yearasicapi stores each purchased extract for 12 months and the section endpoints read it for free, so there is nothing to cache locally. Purchase again only when a new document appears in the free document list
Historical company extractSame as current plus cessation lodgementsSame approach; it is the more expensive product, so check the document list before repurchasing
Document metadata and imagesNever. A processed document is immutableCache indefinitely by document number. Downloaded PDFs can be stored permanently
Name search resultsNew registrations and name changes dailyCache for a day at most
Weekly summariesPublished once per completed weekCache permanently once retrieved
Code tables and form scheduleRarely, without noticeCache for a day; tolerate unknown codes regardless
Person extractsAny appointment, cessation or shareholding change at any of the person's companiesStored for 12 months like company extracts; repurchase when you need a newer snapshot. Person ids from a search expire after 30 days

Check the document list before re-buying an extract

The document list is free and always live. If you already hold an extract and want to know whether it is stale, call GET /v1/companies/{id}/documents?limit=1 and compare documentNumber with the newest document embedded in the extract (or the asOf timestamp). A new number means something changed and a fresh purchase will differ; the same number means the extract you hold is still what ASIC would send. See free lookups, extracts and orders.

On this page