Paulund
Subscribe
← Changelog

Bullion API24 October 2026, 3 min read

Requiring a verified email address for Bullion API keys

No price data until the email is verified.

In July I added email verification to the Bullion API. The risk I cared about was API access, so an API key can't read price data until its owner has verified their email address.

The first version: gate the API, not sign-in

A single global switch, like a framework's requireEmailVerification, is the convenient way to add verification. It also blocks sign-in, the dashboard, key management and the verification flow itself. A verification email can be delayed, land in spam or go to a mistyped address, and with sign-in blocked each of those gets harder to sort out. The person can't even reach the screen that explains how to verify.

So the first version put the check in front of API access and nowhere else. An unverified account could sign in, open the dashboard, manage its API keys and request another verification email. Its keys couldn't read price data.

What a blocked request gets

A missing, invalid or revoked key gets the same 401 responses as before. A valid key whose owner hasn't verified their email gets a 403 with a stable code a client can handle:

{
  "status": "error",
  "error": {
    "code": "email_not_verified",
    "message": "Verify your email address before using the API"
  }
}

The order of the checks

The check returns before quota accounting and request logging. One shared helper validates the key, looks up the owner's verification state and stops there for an unverified owner:

validate API key
check email verification
check quota
serve price data
log the request

If the verification check ran after the quota check, a blocked call would use up the allowance of someone who is waiting for an email and trying again. If it ran after logging, the request records would show API use that never happened.

A valid key that can now get a 403 is a change to the API contract, so the OpenAPI description documents it. It started on the two price-data endpoints and is now on every data endpoint. The tests cover the unverified path, including that no quota is used and no request is logged, as well as the verified path and the existing 401 responses.

What I changed in October

In October I changed sign-up itself. Email sign-up now takes only an address. The account has no password until the owner opens the emailed link and chooses one, and opening that link confirms the address and signs them in. Nobody can register someone else's address with a password of their own and wait for the owner to verify it.

A session on an account that still hasn't proven its address can now do much less than in July. It can't create API keys, connect an MCP client, change the email address, or change its profile or billing. It can still resend the verification email, reset the password, sign out or delete the account, and the dashboard shows a "Verify your email" banner with a resend button. Accounts created before the change get reminder emails with the same link.

The 403 is still there for any key whose owner hasn't verified.

More from Bullion API

Every incident, from open to close.24 October 2026Building a status page for the Bullion API that explains its incidentsGold in today’s dollars.21 October 2026Adding an inflation-adjusted gold price to the Bullion API