Engineering

How to register domains in bulk through an API

Register domains in bulk through an API by checking an exact list first, then sending one idempotent request per domain. The safe workflow, and its limits.

The short answer

Checking domain availability in bulk and registering domains in bulk are two different operations. A list of exact names can be checked for availability in one API call, but each domain actually bought should be its own registration request with its own idempotency key, so one failure or one already-taken name never blocks the rest of the batch. A row marked "unknown" means the registry did not answer in time, and a row marked "premium" means the name is not sold here yet; neither means the name is taken. As of October 2026, ResellerHQ's POST /v1/domains/check checks up to 100 exact domain names in one call, and the dashboard's Bulk import page does the same from a pasted list or an uploaded CSV file, though domain registration itself still runs in the sandbox only.

To register domains in bulk through an API you need two operations rather than one, and conflating them is a frequent mistake in a bulk workflow. Checking is a read: you hand over a list of names and get back which ones are free. Registering is a write that spends money and can only ever happen once per name, so it has to be sent, tracked and retried differently from a check. This article walks through both, using the public documentation and route behaviour of ResellerHQ's domains API as the worked example, and links out rather than repeating the per-vendor rate-limit figures and the idempotency-key pattern already covered elsewhere on this site.

Why are checking and registering two different operations?

A check costs nothing and changes nothing: you send a list of names and get back a verdict for each. A registration charges your wallet and, if it succeeds, takes a name off the market for good, so it cannot be batched the same carefree way a check can.

That distinction shows up directly in how the API is shaped. ResellerHQ's check route takes an array of up to 100 domains in one call and returns a row per name with no money moved (Domains). Its register route takes exactly one domain per call, not an array, and every successful call debits the wallet for that name's price times the years registered (Domains). A batch of fifty names you want to buy is therefore one check call and up to fifty separate register calls, not two calls total.

Sending registrations one at a time is also simpler to reason about when something goes wrong. If a check fails, you retry the whole check: nothing was committed. If one registration out of fifty fails, nothing about the other forty-nine changes, because they were forty-nine separate requests in the first place.

Is a single search call the same as a bulk availability check?

No. A name search answers "what are my options starting from this one word", and a bulk check answers "which of these exact domains can I buy right now." They serve different stages of the same job.

ResellerHQ's GET /v1/domains/search takes a bare name or a full domain and prices it across every ending on offer, which is the feature built for finding a name: "Search one name across every ending at once" is literally one of the three things the product's domains page lists it can do. A premium name is left out of search results entirely, because it has no single yearly price to show next to the others, and a name the registrar could not answer for comes back marked unknown rather than being called taken (Domains).

POST /v1/domains/check is a different endpoint built for a different question: given a specific list of up to 100 exact domains, which are available to buy. It is the right tool once you already have the list, whether that list came from a customer's intake form or a CSV of a portfolio you are consolidating.

GET /domains/searchPOST /domains/check
InputOne bare name or full domainUp to 100 exact domain names
What it answersWhich endings are available for this name, and at what priceWhich of these specific names are available
Premium namesLeft out of the resultsReturned, marked premium, with a null price
A name the registrar could not answerMarked unknown, kept in the results with its ordinary priceMarked unknown, with a null price
Good forFinding a nameBuying a list you already have

Source: Domains.

Running a search once per ending you care about, across a long list of names, is not a substitute for a bulk check: it is slower, it returns pricing for endings you may not want, and it still is not checking the exact set of domains you intend to buy. Use search to find names, and check to confirm the ones you already picked.

What do "unknown" and "premium" rows mean in a bulk check?

Neither means "taken," and treating them that way loses a sale or wastes a retry on a name that was never going to come back differently.

A row marked unknown means the registry did not answer the check in time. ResellerHQ's docs are explicit that an unknown row keeps its ordinary price and should simply be tried again shortly (Domains); it is a timing problem, not an availability answer. A row marked premium means the registry prices that name outside its normal per-year fee, and ResellerHQ specifically does not sell premium names through the API yet, so a premium row comes back with a null price and cannot be registered - attempting it answers 422 premium_domain (Domains). Nobody necessarily owns a premium name; it is simply not on sale here yet, which is a different fact from a name someone else has already registered.

A full bulk check can report six distinct outcomes for a single name, and only one of them is a straightforward purchase decision:

Row saysWhat it meansRegister it now?
AvailableFree to register at the price shownYes
TakenSomeone else already owns itNo
Ending not soldThat TLD is not on offer at allNo
Not a valid nameThe name itself is malformedNo, fix the name
Could not check (unknown)The registry did not answer in timeNot yet; check it again
PremiumPriced outside the normal fee; not sold here yetNo

Source: Domains.

How do you register domains in bulk through an API safely?

The safe pattern is: one check call for the whole list, then one independent, idempotent register call per name you decide to buy.

  1. Build the exact list. Collect the specific domain names you want, not a topic to search broadly. This might come from a customer's order form or a CSV export of names you are migrating.
  2. Check the list in one call. Send up to 100 names to POST /v1/domains/check. Anything longer than 100 is sent as more than one check call.
  3. Keep only the rows marked available. Leave taken, unsold, invalid and premium rows out of the next step entirely, and set unknown rows aside to check again shortly.
  4. Register each one as its own request. For every name you are buying, send a separate POST /v1/domains with a fresh, unique Idempotency-Key header on that call. If a connection drops mid-request, retrying with the same key cannot register the name twice; the server replays the first outcome instead of running it again (Domains). Our idempotency keys and webhooks guide covers the pattern and its 409/422 behaviour in detail, so it is not repeated here.
  5. Let a pending registration settle on its own. A registration can come back pending while the registrar finishes the order; it becomes active by itself with nothing further to send (Domains).
  6. Retry only what failed. A name that failed for a reason that might change, such as a timeout, can be retried with a brand-new idempotency key for that new attempt; a name that failed with a definite answer, such as 409 domain_taken, should simply be dropped from the batch.

Doing it this way means a batch of fifty names you want to buy is one check call and up to fifty independent register calls, each of which can succeed or fail without touching the others.

How do rate limits affect a bulk domain workflow?

They set how fast step 4 above can run, and the ceiling varies enormously by vendor, so check it before you fire off fifty register calls back to back. Published domain reseller API rate limits differ by a factor of more than 100; the full per-vendor table, with each figure's own source link, is already published in domain reseller APIs compared and is not repeated here. If a vendor's limit is low, send your register calls with modest concurrency and a queue rather than all at once, and read any rate-limit response headers the vendor documents instead of hard-coding a number.

How do you import a domain portfolio from a CSV file?

By checking the names in the file the same way you would check a list typed by hand, then registering the available ones one at a time; ResellerHQ's dashboard does exactly this for you. Its Bulk import page, under Domains, takes a dropped or uploaded .csv or .txt file, guesses which column holds the domain names, and lets you confirm or change that column before checking anything.

From there, the page follows the same shape as the API workflow above:

  • It checks up to 100 names from the file in one call to /domains/check; from a longer file, only the first 100 are checked.
  • Each row is shown with its verdict: available, taken, ending not sold, not a valid name, could not check, or premium, using the same six outcomes described above.
  • Rows marked unknown or premium can never be ticked for registration, so they cannot be bought by mistake.
  • Registering the ticked rows sends one POST /domains per domain, each with its own freshly generated idempotency key, running four at a time by default. A failure that leaves your wallet able to pay, such as a name someone else bought moments after the check, is reported against that row only and the rest of the batch keeps going. Running out of funds is the exception: nothing after it could be paid for either, so the remaining rows are not tried.
  • Anything that fails can be retried from the same screen without re-checking the whole file again.

If you are building your own CSV importer against the API rather than using the dashboard, this is the behaviour to copy: check the file's names in batches of up to 100, then register each confirmed name as its own idempotent request, and surface per-row failures instead of failing the whole import.

Where does ResellerHQ fit for bulk domain registration today?

ResellerHQ's domain availability check and its dashboard import page both work today, in the sandbox; live domain registration does not yet, and that is worth being direct about before you build against it. POST /v1/domains/check checks up to 100 exact names per call, POST /v1/domains registers one at a time with an optional Idempotency-Key header whose outcome is stored for 24 hours, and the dashboard's Bulk import page runs both of those for you from a pasted list or an uploaded CSV file (Domains). Domains are listed as "Open in the sandbox" on the product overview, and on the live side every domain route currently answers 422 not_available; sandbox domains are not registered anywhere (Domains).

So a bulk import built against ResellerHQ today is real end-to-end testing of the check-then-register workflow, the idempotency behaviour, and the CSV import page itself, against sandbox data rather than a live registry. For how this compares with vendors whose domain APIs are live now, see domain reseller APIs compared, and for a fuller test plan covering retries and webhooks before any go-live, see how to test a reseller API integration in a sandbox.

Questions

  • No, not as one call. A bulk availability check can cover up to 100 exact names in one request, but registering is a financial transaction against your wallet, so it is sent as its own request per domain, each with its own idempotency key. That way one domain being taken, over your balance, or failing for any other reason does not stop the rest of the batch.
  • A search takes one name and prices it across every ending a registrar offers, which is useful for finding a name to begin with. A bulk check takes a list of exact domains, up to 100 at a time, and tells you which of those specific names are free to buy. They answer different questions, and a search result is not a substitute for checking the exact list you actually want to buy.
  • It means the registry could not be reached to answer in time, not that the name is taken. Treat it as a row to check again shortly, separately from the rows marked available or taken.
  • A premium name is one a registry prices outside its normal yearly fee. ResellerHQ does not sell premium names through its API today, so a premium row comes back with no price and cannot be registered. It is a distinct outcome from "taken": nobody necessarily owns it, it is simply not available to buy through the API yet.
  • An idempotency key makes one specific request safe to retry; it has no meaning across two different domains. Giving each registration its own key means a dropped connection on domain A can be retried safely without touching domain B's order, and a batch of 40 registrations becomes 40 independent, individually retryable operations instead of one all-or-nothing call.
  • Up to 100 exact domain names in one call to POST /v1/domains/check. If you are writing your own client, send a longer list as more than one call of 100 or fewer. The dashboard's own Bulk import page does not split a long file: it checks the first 100 names in it, and says so on screen alongside the number of names the file held.

Sources

  1. IETF: The Idempotency-Key HTTP Header Field (draft 07) ietf.org

Keep reading

More on selling under your own name

Start selling under your own brand

  1. Sign up with an email, no call needed1 minute
  2. Get test keys and $5,000 of pretend moneyInstantly
  3. Take order #0001 under your own nameToday