Developers / Authentication
Authentication
Keys, rotation, IP restrictions, and what to do when a key stops working.
Every /v1 request except /v1/ping and the API description needs a key.
curl https://api.mrvin.com/v1/account \
-H "Authorization: Bearer mrvin_live_your_key_here"X-Api-Key: <key> is accepted as an alternative if that fits your client better. Both are equivalent. Authorization is the documented form.
Keys
Keys begin with mrvin_live_ followed by 40 random characters. The prefix makes them recognisable in your own configuration and lets code scanning tools spot one that has leaked.
We store only a hash. The key is shown once, when it is issued. If it is lost we cannot recover it and will issue a new one.
Keeping a key safe
- Server side only. A key is a bearer credential: anyone holding it can spend your balance. Never ship one in a browser, a mobile app, or anything a user can read.
- Headers only. Keys in query strings end up in access logs, proxy logs, browser history and referrer headers. We reject
?api_key=with a400rather than letting it work quietly. - Environment or secret manager, not source control.
- One key per system. Separate keys for separate integrations mean you can revoke one without taking the others down, and usage is attributable.
Rotating
Rotation has no downtime, because two keys can be active at once.
- Ask us for a new key.
- Deploy it.
- Confirm traffic has moved. We can see which key is being used.
- Ask us to revoke the old one.
A revoked key stops working immediately. If a key has leaked, say so and we will revoke it straight away rather than waiting for a clean cutover. An exposed key is worse than an outage.
IP restrictions
We can restrict your account to a set of source addresses. It applies to every key on the account, not to one key. Send us the addresses and we will set it up. Single addresses and CIDR ranges both work.
With no list set, any address may call. The moment one is set, everything else is refused.
A refused request gets 403 IP_NOT_ALLOWED, and the message names the address we saw.
{"error": {"code": "IP_NOT_ALLOWED",
"message": "Your account is restricted to specific source addresses and 198.51.100.9 is not one of them. Send us that address if it should be.",
"requestId": "req_2f1c..."}}That is deliberate. An IP restriction fails on the day your egress address changes without anyone deciding to change it: a new gateway, a failover, a provider reassigning a block. If the refusal looked like a bad key you would spend the outage checking your credentials. The address in the message is the one to send us.
Two things worth knowing before you turn this on:
- It is checked after your key. A bad key from an allowed address is still
401. - We judge on the address that reaches us. If your traffic leaves through a proxy, a gateway or NAT, list that address and not your own servers.
When authentication fails
401 UNAUTHORIZED covers a missing key, an unknown key, a revoked key and an expired one. They answer identically on purpose. Distinguishing them would let anyone holding a stray key learn whether an account exists.
If you are seeing 401 with a key you believe is good, check you copied the whole thing including the prefix, that it has not been rotated out from under you, and that you are sending it as a header rather than a query parameter.