Authentication
The first 2,500 requests a day from an address need no key. A key is for everything past that: it decides whose credit or package a request draws on and which machines may use it, and it gives you a usage history. Keys are free and take a minute to get.
Without a key
Send the request with no credential at all and it is answered. Every address gets 2,500 requests a day this way, counted from 00:00 UTC across every endpoint and every drop-in host, with the same data and the same answers as a paying account. Past that the API answers 429 quota_exceeded with a Retry-After header until the reset; nothing is charged and nothing is queued.
Two things to know. Addresses that belong to the same network (the same IPv4 /24 or IPv6 /48) share one allowance, so a busy office, a campus or one cloud region can run through it faster than a single machine would. And a network and the keys used from it draw on the same allowance: requests made without a key reduce what a key used from that network gets today, and free requests made on that key reduce what the network gets without one. Signing up therefore adds credit, packages and history, not a second free 2,500 from the same place.
Getting a key
Sign up at www.mygeocode.com/signup with your name, an email address and a password. Then confirm your address from the email we send: until you do, the account cannot log in or use the API, and accounts that are not confirmed within 24 hours are deleted. Once confirmed, your first key is waiting under API keys in the dashboard, where you can see it again whenever you need it. Create as many further keys as you like under API keys, give each a label (one per server or per application is a good habit), and revoke any of them at any time.
An account has 2,500 free requests a day, shared by all of its keys and counted from 00:00 UTC across every endpoint and every drop-in host. Past that, requests draw on the account's prepaid credit at €0.0001 each, unless the key belongs to an Unlimited package.
Sending the key
Any of these works on every host. Prefer the header: query strings end up in server logs, browser histories and proxies.
$ curl -H "X-API-Key: mg_7f3c2a19e04b...d1" "https://api.mygeocode.com/v1/reverse?lat=51.5&lon=-0.12"
$ curl -H "Authorization: Bearer mg_7f3c2a19e04b...d1" "https://api.mygeocode.com/v1/reverse?lat=51.5&lon=-0.12"
$ curl "https://api.mygeocode.com/v1/reverse?lat=51.5&lon=-0.12&key=mg_7f3c2a19e04b...d1"
$ curl -u "mg_7f3c2a19e04b...d1:" "https://api.mygeocode.com/v1/reverse?lat=51.5&lon=-0.12"On api.mygeocode.com the query parameter may also be called apikey or api_key. On the drop-in hosts the key also goes wherever the original provider's key went: key for Google, Bing, Geocode.Farm, OpenCage, LocationIQ, TomTom, MapQuest and ip-api; apiKey for HERE and Geoapify; access_token for Mapbox; api_key for Geocodio; access_key for PositionStack and ipstack; token for ipinfo. Nominatim and Open-Elevation clients add key= or a header, since those two services have no key of their own.
Beyond the query parameter, these ways of sending credentials are accepted on every host, so a client library that authenticates the provider's way needs no change: the X-API-Key header, Authorization: Bearer, HTTP Basic authentication with the key as the user name or the password (what curl -u KEY: sends, and what the ipinfo examples use), the X-Goog-Api-Key header that Google's clients send, and the X-API-Token and X-Access-Token headers. A key in a form body is read too, for the endpoints that are posted to. Changing the host name and the key is the whole migration.
Two kinds of key
| Pay-as-you-go key | Unlimited key | |
|---|---|---|
| How you get it | Create it in the dashboard, free | Comes with each Unlimited package (€50 per month) |
| Free requests | 2,500 a day | All of them |
| Above the free allowance | €0.0001 each from the account's credit; 402 when the balance is empty | Nothing |
| IP slots (rolling 24 hours) | 2 | 3 |
| When the package lapses | The key keeps working as a pay-as-you-go key |
IP slots
A key may be used from a limited number of IP addresses at a time: two for a pay-as-you-go key, three for an Unlimited key. The rule is rolling, per address:
- The first time an address uses the key it takes a slot, and holds it for 24 hours from that first request.
- When those 24 hours are up the slot frees on its own, whatever the other addresses are doing. If the same address comes back later, it takes a slot again.
- A request from a new address while every slot is held is refused with
403and the codekey_ip_limit. The message says when the next slot frees. Refused requests are not counted.
So if two servers first used a key at 02:00 and a third at 04:00, two slots free at 02:00 the next day and the third at 04:00. The dashboard shows which addresses hold a key's slots and when each frees. Need more machines? Create more pay-as-you-go keys, or add more Unlimited packages; each package brings its own key.
The limit exists because keys leak. With it, a key that ends up in a public repository is worth very little to whoever finds it, and since credit is prepaid, nobody can spend more than the balance you loaded.
Keys and browsers
Keep server keys out of JavaScript and mobile apps. Anyone can read a key out of a page, and every visitor is a new IP address, so a server key's slots are gone after the second or third visitor.
For a web page, create a browser key in the dashboard. It starts with mg_pub_ and is made to be public. It works only from scripts on the one website you name for it, and it has no IP slots, because every visitor calls from their own address. example.com and www.example.com count as the same website; any other subdomain, and any other website, needs a browser key of its own: one website per key.
Browsers send the page's address with every request, in the Origin or Referer header, and a web page cannot change it, so another website cannot use your key. Requests without that header, from a server, an app or the command line, are refused with 403 browser_key_origin. A program outside a browser can fake the header, so two more limits protect you: each visitor (an IPv4 address, or an IPv6 /64) may make 60 requests a minute on a browser key (429 rate_limited), and any key can have a daily spending limit in euros, set on its key page (429 key_daily_cap once it is reached). Otherwise a browser key works like any other key: on every endpoint and every drop-in host, from the account's free allowance and credit, or as the key of an Unlimited package.
Without a key, a call made by a script on a web page counts like any other keyless call: against the free allowance of the visitor's network. To have all of a website's calls counted together, on your account's allowance and credit, use a browser key.
A mobile or desktop app has no website to check, so it cannot use a browser key: call the API from your own server and keep a server key there. The JavaScript map drop-ins load without a key and take a browser key for their geocoding calls.
Revoking and rotating
Revoke a key in the dashboard and it stops working within a minute. Create the new key first, deploy it, then revoke the old one; both work in the meantime. Keys never expire on their own.
Refusals
| HTTP | code | Meaning |
|---|---|---|
| 401 | missing_key | No key was sent and keyless access is switched off on this server (it is on by default). |
| 429 | quota_exceeded | The address has used its free allowance for the day without a key (for calls from scripts on a web page: the website has); Retry-After says how long until the reset. |
| 401 | invalid_key | The key does not exist. |
| 401 | key_revoked | The key was revoked. |
| 402 | no_credits | Free allowance used for the day and the account balance is empty. |
| 403 | key_ip_limit | All of the key's IP slots are held by other addresses. |
| 403 | browser_key_origin | A browser key was used from another website, or without an Origin or Referer header. |
| 429 | rate_limited | One visitor sent more than 60 requests a minute on a browser key; Retry-After says when to try again. |
| 429 | key_daily_cap | The key has reached the daily spending limit its owner set; it resets at 00:00 UTC. |
| 403 | account_suspended | The account is suspended; contact support. |
| 403 | email_unverified | The account has not confirmed its email address yet. |
| 403 | package_suspended | The Unlimited package behind the key is suspended; contact support. |
None of these count toward the allowance or cost credit. On the drop-in hosts they are reported in the original provider's shape; see compatibility.