# Keys and origins

Each route needs an API key, except [Get dataset details](/docs/api#getMeta). Create keys on the dashboard. [Each plan](/#plans) sets the number of keys, and counts the units of all keys of the account together.

## Select the key

| Where your code runs                    | Key                       | How to send the key                              |
| --------------------------------------- | ------------------------- | ------------------------------------------------ |
| A server, a script, or a background job | Secret key, `onde_sk_...` | `Authorization: Bearer` header                   |
| A web page                              | Public key, `onde_pk_...` | `key` query parameter                            |
| A mobile app or a desktop app           | Secret key on your server | Send the requests of the app through your server |

A mobile app or a desktop app has no web origin, so a public key does not work in it. Do not put a secret key in an app, because each user can read the app.

## Secret keys

Send a secret key in the `Authorization` header.

```bash
curl "https://api.onde.earth/v1/cities/search?q=lisbon" \
  -H "Authorization: Bearer $ONDE_KEY"
```

The API refuses a secret key in the URL, because servers and proxies write URLs to their logs.

The dashboard shows a new secret key one time. Copy the key when you create it. If you lose a secret key, or if it leaks, revoke it on the dashboard and create a new key.

## Public keys

Send a public key in the `key` query parameter.

```js
const url = new URL('https://api.onde.earth/v1/cities/autocomplete')
url.searchParams.set('q', 'kyoto')
url.searchParams.set('key', 'onde_pk_...')
const response = await fetch(url)
```

Do not send a public key in the `Authorization` header. A browser sends an `OPTIONS` request before a request with this header, for each new URL. Each new text in a city field gives a new URL, so the header doubles the round trips.

Each visitor of your site can read a public key. The API accepts the key only from its allowed origins, so a different website cannot use it in a browser. A script outside a browser can send any `Origin` header. For this reason, a public key also has a limit of 10 requests per second for each IP network, and the monthly limit of the plan applies.

## Allowed origins

Each public key has 1 to 20 allowed origins. Edit the origins of a key on the dashboard.

An origin is a scheme, a host, and an optional port, such as `https://www.example.com`. The API compares the full origin:

- `https://example.com` does not accept `https://www.example.com`. Add both if your site uses both.
- `http://localhost:4321` does not accept `http://localhost:3000`. Add the origin of each local development server.
- `https://*.example.com` accepts `https://shop.example.com`. It does not accept `https://example.com` or `https://a.shop.example.com`.

Write the origin with no path and no slash at the end.

## Fix key errors

| Error                                                          | Cause                                                       | Fix                                          |
| -------------------------------------------------------------- | ----------------------------------------------------------- | -------------------------------------------- |
| `origin_not_allowed` in the browser                            | The origin of the page is not an allowed origin of the key. | Add the exact origin of the page to the key. |
| `origin_not_allowed` from curl or a server                     | A public key needs the `Origin` header of a browser.        | Use a secret key.                            |
| `unauthorized` with "A secret key is not accepted in the URL." | The secret key is in the `key` query parameter.             | Send the key in the `Authorization` header.  |
| `unauthorized` with "The API key is not valid."                | The key is revoked, or a character is missing.              | Copy the key again, or create a new key.     |
