Skip to main content
Each API key, each AI connection and each organization has a budget of calls a minute, by the kind of call:
  • A call spends from its key’s budget, then from its organization’s. The organization’s budget is shared by all its keys and AI connections, so one busy program can slow the others: give each program its own key and spread its calls.
  • People in the app spend none of it. A person’s work in the app never takes from these budgets, so a program that spends them all never locks your team out.
  • Budgets refill continuously, not at the top of each minute, and hold only a few seconds’ worth of calls at once: a steady pace gets more done than bursts.

Know what is left

Get the calling credential answers your key’s limits and its remaining calls of each kind, the lower of what its own budget and its organization’s still hold. It counts against no limit and takes no place among the calls in flight, so you may call it whenever you need to.

Past a limit

A call past a budget answers 429 with the code core.rate_limited and a Retry-After header, the whole seconds to wait. It did nothing: wait that long and send it again, never in a tight loop.

Calls in flight

Keep at most calls of your organization’s keys and AI connections running at once. A call beyond them may answer 429 core.rate_limited before it does anything, with its own Retry-After. To read faster, ask for bigger pages rather than more calls at once.

Unfinished jobs

Long work, such as an import or an export, runs as a job: its call answers 202 Accepted with a jobId, which Get a job follows until it ends. An organization holds at most unfinished jobs, whoever started them: waiting, paused or running. A key’s or an AI’s start beyond them answers 429 with the code core.job_limit_reached and a Retry-After of seconds, and starts nothing. A person’s start in the app is never refused. A job’s file, such as an export’s, is read through a link from Get a job’s file link, which works for minutes: ask for a new one when it expires.

Retry a write safely

A write whose answer never arrived, because the connection dropped or timed out, may or may not have happened. Send it with an Idempotency-Key header, a value of your own of at most characters, such as a UUID made for that one write, and send the same key on every retry of it:
  • The first call does the write; a retry with the same key and the same request answers the first call’s answer, without doing it again, for hours.
  • While the first call still runs, a retry answers 409 core.idempotency_in_progress: wait, then retry.
  • The same key with another request, another body or another path, answers 422 core.idempotency_mismatch.
  • Each value is your credential’s own: another API key’s call with the same value is a call of its own.
  • A value that is empty or too long answers 400 core.bad_request.
  • A call that failed stores nothing, so its retry runs again.
These writes honor an Idempotency-Key; on any other, it changes nothing: Cancel a job, Restore a version, Start an import, Inspect an import file, Check an import, Fetch a file from a URL, Write an import’s results, Start an export, Create an export template, Create a saved view, Connect a store, Create a product and Duplicate a product.