Help Centre

26 answers to the things that actually go wrong, grouped by what you are seeing. Search this page for the reason string from your logs.

Keys and 403s

My key works in curl but returns domain_mismatch from the browser

domain_mismatch

From curl you are probably passing domain= explicitly. From a browser you are not, so the gateway falls back to the Origin header, then Referer — and those carry whatever the browser decided, which on a local dev server is localhost rather than your production domain.

Two fixes, depending on where you are:

  • In production, send domain explicitly from your server. Never rely on headers you do not control.
  • For local work, issue a second key bound to localhost and select it by environment.

Does a key bound to example.com work on app.example.com?

domain_mismatch

Yes. Subdomains are matched against the lock, so a key on the apex accepts anything beneath it.

It does not work the other way. A key bound to app.example.com refuses example.com, because the lock is the more specific name. Bind to the apex if you want both.

I ticked no scopes and everything works — is that right?

insufficient_scope

Yes, and it is worth understanding. A key with no scopes selected has full access. The check only runs when you send a scope parameter, and a key with an empty scope list satisfies any scope asked of it.

That is the permissive default so nothing breaks on day one, but it means least-privilege is opt-in. Give each integration only the scopes it needs, and start sending scope on the endpoints that matter.

I lost a server key. Can you show it to me again?

invalid_key

No — server keys are stored hashed and displayed once, at creation. There is no path in the system that can reveal one afterwards.

That is deliberate: a key we could show you again is a key anyone holding your dashboard session could show themselves. Rotate the key, deploy the new value, then revoke the old one.

My IP allowlist blocks my own server

ip_not_allowed

Almost always because the allowlist holds your office or laptop IP rather than your server's outbound address. They are rarely the same, and behind NAT or a load balancer the address we see may be neither.

Log what the gateway reports as the caller IP for one failing request and allowlist that. If your host rotates egress addresses, allowlist the range or leave the list empty and rely on the domain lock and scopes instead.

Domain verification

I added the TXT record hours ago and it still will not verify

domain_not_verified

The overwhelmingly common cause: your DNS panel appended your domain to the Name field a second time.

Cloudflare, Namecheap, GoDaddy, Hostinger and Squarespace all add the zone to whatever you type. Paste the fully qualified _buildapi-verify.example.com and you have actually created _buildapi-verify.example.com.example.com, which resolves to nothing — while looking completely correct in the panel, which is what makes it so hard to spot.

Enter just _buildapi-verify. Check it from a terminal before pressing Verify again:

dig +short TXT _buildapi-verify.example.com

If that prints nothing, the record is not where we are looking, whatever the panel shows.

Do I have to verify every subdomain separately?

domain_not_verified

No. Verification is per domain and a key bound to the apex covers its subdomains, so proving example.com once is enough for keys bound there.

A key bound specifically to app.example.com is verified against that name, so it needs its own record at _buildapi-verify.app.

Can I verify without touching DNS?

domain_not_verified

Yes. Serve the token as plain text at /.well-known/buildapi-verify.txt over HTTPS, with nothing else in the file. Either method satisfies the check.

The file route is usually faster if you can deploy quickly; DNS is better if the site is not yours to deploy to.

It verified once and now says unverified again

domain_not_verified

Verification is re-proved periodically, so a domain that stops publishing its record lapses. Leave the TXT record or the file in place permanently — removing it after verifying is the usual cause.

One failed lookup does not do it. It takes three consecutive failures, so a transient DNS blip never cuts a working customer off, and the message tells you how many are left before it lapses.

A confirmation also goes stale on its own: if we have not been able to see your proof for 30 days, the domain stops being trusted even if nothing explicitly failed. A domain being re-checked normally is re-confirmed several times inside that window, so this only bites a domain nobody can verify any more.

I deleted my DNS record and everything kept working. Why?

domain_not_verified

It should not, and until recently it did not stop. Pressing Re-check would correctly report the record missing, but the verification stayed in place — and worse, the act of pressing it pushed the automatic re-check a week into the future, so asking the question prevented the answer.

Now a failed check counts toward the same three-strike grace whether you triggered it or the background job did, and the third one lapses the domain. Once lapsed, every key bound to it is refused with domain_not_verified until the record is back and you verify again.

Can I move a key to a different domain?

transfer

Yes, at any time. Changing the domain on a key is a transfer: the key immediately stops working and does not work again until you have proved the new domain, exactly like setting up a key for the first time.

That is what stops one key quietly serving several sites — not a waiting period, but the fact that a moved key is unverified until its new home is proved. A verification record you already hold for the new domain counts, so moving back to a domain you have proved before is immediate.

Limits and 429s

My allowance reset on the wrong day

usage_limit_exceeded

It resets on your subscription anniversary, not the first of the month. Subscribe on the 20th and every cycle runs 20th to 20th.

If you are looking at a date that seems early, check when the subscription actually started — the dashboard shows the exact refill date next to your usage, and the 429 response names it too.

Is the call allowance shared across all my keys?

usage_limit_exceeded

Yes — it is one pool for the account. The number on your plan is the total for the cycle across every key you hold, so creating more keys does not create more allowance.

When the pool is spent every key returns 429 at once. If only some of your traffic is failing, you are looking at the per-minute rate limit instead, which is set per key and throttles them independently.

The free tier stopped after a month and never came back

usage_limit_exceeded

Working as intended. The free allowance is a lifetime total, counted from the day the account was created — it does not refill monthly.

Paid plans refill every cycle. The 429 body says which of the two you are on rather than making you guess.

I get 429 rate_limited but I am nowhere near my monthly allowance

rate_limited

Those are two separate limits. rate_limited is the per-minute burst guard on the key; usage_limit_exceeded is the monthly allowance. You can hit either without touching the other.

Raise or clear the per-minute limit on the key. If it is a batch job, add a small delay between calls rather than removing the guard — it is the thing that stops one runaway loop spending a month of allowance in a few minutes.

What should my code do when it gets a 429?

429

Back off and retry, rather than failing the user immediately. Wait, then retry with the interval doubling each time, and give up after a few attempts.

Branch on reason before deciding: rate_limited usually clears within the minute, while usage_limit_exceeded will not clear until the cycle resets — retrying that in a loop just burns your own resources.

Key expiry and renewals

How long does a key last?

expired

30 days on every paid plan — the same rule on all tiers.

Keys share one expiry anchored to your subscription rather than each counting down from when it was created. Make a key on the day you subscribe and it has 30 days; make another the next day and it has 29, because both expire at the same moment.

I pay yearly — do my keys die after 30 days?

expired

No. The 30-day window rolls forward automatically while your subscription is live, so a yearly subscriber never re-issues keys.

The window exists so that no key is a credential that lives for a year without the subscription behind it being checked again. You do not have to do anything for the roll to happen.

My subscription lapsed. Are my keys gone?

expired

Not deleted — they run out their current window and then stop. Nothing is destroyed, and resubscribing reactivates them.

Downgrades never delete keys either. If you move to a plan that allows fewer than you currently have, the change is blocked at checkout with the number to revoke, so you choose which stay live rather than us choosing for you.

Billing

I upgraded mid-month. Was I charged twice?

billing

No. A change is priced against what is left of the period you already paid for: the unused fraction becomes a credit and you pay only the difference.

If the credit covers the new plan entirely, nothing is collected at all and the surplus is added to the end of the term as time rather than held as a balance.

Why can I not switch from yearly to a monthly plan?

billing

Because a yearly subscriber can be holding ten months of credit, and spent against a monthly plan that would be most of a year free.

Switch to another yearly plan, or wait until the current year ends. Monthly subscribers can move either way — monthly to yearly is an upgrade and is credited normally.

What does the yearly discount actually save?

billing

The discount is set by the operator of this install and shown on the Monthly / Yearly toggle above the plans, along with the effective per-month figure so you can compare like with like.

Whatever it is set to, a year never costs more than twelve monthly payments.

Integration

Should I check the signature, or is authorized:true enough?

signature

Check it if the answer is worth money. authorized: true on its own is a claim in a JSON body; anything that can sit between you and us can write that.

The signature is an HMAC keyed by your API key, so only somebody holding the key can produce a valid one. Send a random nonce with the request too — it is echoed inside the signed payload, which is what stops a captured response being replayed later.

What happens to my site if your gateway goes down?

outage

It keeps working. The snippet remembers the last answer it was given and rides out an outage on it, so a gateway that is unreachable — down, moved, expired — does not take your site with it.

That is bounded, and it is the only thing that bypasses a check. A gateway that answers and says no is a no: a refusal closes the gates immediately and is never ridden out on a cached yes. And once the remembered answer is older than a few days, it stops counting too, because a service that has gone away permanently should not leave every site running for ever.

If you are writing your own integration rather than using our snippet, match that rule: fall back only on a network failure, never on a refusal, and put a limit on how long you will do it.

Should I verify on every request, or cache the result?

integration

Verify on every request that matters. It is one call, it is what enforces the quota and the domain lock, and caching a positive answer means a revoked key keeps working until your cache expires.

Where you need to reduce calls, cache briefly — tens of seconds, not hours — and always re-verify anything that grants access to money or personal data.

Can I put a key in my front-end JavaScript?

integration

A client key, yes — that is what they are for, and the domain lock is what makes it survivable. Someone can read it, but pasted into their own site it stops working.

A server key, never. Anything in a browser is readable by anyone who opens developer tools, and a server key is protected only by secrecy.

Understand what the domain lock is and is not: it stops casual reuse, not somebody determined enough to proxy requests through your own site. Anything valuable should be verified server-side as well.

Not here?

The documentation goes deeper on how each check works. If your problem is not covered by either, send it to us — answers get added here rather than disappearing into an inbox.