Apps and keys
Every key belongs to an app. An app is a name for one integration, such as "Acme estimator" or "Nightly sync". A company can have up to 25 apps. Apps and keys are free on every plan, Free included.
Make an app
An admin opens Settings → Developer → Apps → New app and fills in:
- Name (up to 80 characters), and optionally a Description (up to 500), Homepage and Support email.
- Scopes: what the app may do. Any scope except
admin:org. See Scopes.
The app works in your own company at once. Letting other companies install it is a separate, optional step; see Let other companies install your app.
Make a key
In the app, under Keys, an admin clicks New key and picks:
- Name: 1 to 80 characters, such as "Production" or "Laptop".
- Scopes: All of the app's scopes (the default), or Specific ones. A key can never have more than its app.
- Works in: shown only once another company has the app installed. See Company scope.
- Expires: optional. A key set to expire on a day works through the end of that day.
The key is shown once. Copy it then. An app can have 25 active keys. A 26th is refused with
app_key_limit_reached until you revoke one. An expired key still counts until it is revoked.
Key format
exa_live_<40 letters and digits><6-character checksum>
exa_test_<40 letters and digits><6-character checksum>
A key is 55 characters and matches ^exa_(live|test)_[0-9A-Za-z]{46}$. The last 6 characters are a checksum, so a
typo is caught before any lookup. The Developer page shows a key by its start and its last 4 characters.
exa_test_: the app belongs to a sandbox.exa_live_: every other key, including keys of your app in a sandbox where it is installed.
Send the key as a bearer token:
curl https://api.exayard.com/v1/projects \
-H "Authorization: Bearer exa_live_..."
Company scope
This company is the default. The key works only in the app's own company, and it implies that company: leave out
organizationId and the Exayard-Organization-Id header. If a call names another company, or the header and the body
name two different ones, it is refused with 400 company_mismatch.
Every company that installed it appears once your app is installed in another company. Such a key works in each
company that installed the app, so every call must name its company with the Exayard-Organization-Id header (or
organizationId). A call that names none is refused with 400
company_required, except GET /v1/me, GET /v1/installations and the
/v1/organizations calls.
Expiry and revoking
- A key past its expiry is refused with 401
api_key_expired. An admin can make a new one. - Revoke in the key's menu stops it. Allow up to 30 seconds for every server to stop accepting it. After that,
calls get 401
unauthenticated. - Rename changes only the name. The key itself stays the same.
- To swap keys with no gap, make a second key, move your servers to it, then revoke the first.
- Deleting an app revokes all of its keys.
Each key shows when it was last used. That time is updated at most once a minute.
Rate limits per key
A key that works in its own company gets 60 calls a minute of its own, within the app's ceiling of 600 calls a
minute across all its keys and companies. When the key's own limit refuses a call, the 429 says
rate_limit_scope: "app_key". See Rate limits.
Older keys
- API keys starting
ak_keep working. A companyak_key implies its company too. No new ones can be made. They are listed under Legacy keys on the Developer page, where an admin can revoke them. - App secrets starting
xa_app_keep working, and each counts as one of its app's 25 keys. No new ones can be made.
Move to an exa_ key when it suits you. Nothing else in your code changes.
Security
- We keep only a hash. Exayard stores the SHA-256 hash of each key, never the key. That is why it is shown once. A lost key cannot be recovered; make a new one and revoke the old one.
- Keep keys on your server. Never put a key in a browser, a mobile app or a public repository. Read it from an
environment variable, such as
EXAYARD_API_KEY, which the SDK and the CLI read by default. - Give each key only what it needs. Pick specific scopes, set an expiry for short-lived work, and use one key per server or person so you can revoke one without stopping the others.
- If a key leaks, revoke it. Revoke it on the Developer page, then make a new one. The Developer page Logs show each call by app and key, so you can check what the leaked key did.
Every key has a fixed start (exa_live_ or exa_test_) and a checksum, so secret scanners can recognise it. We are
joining GitHub's secret scanning program. Once that is live, a key pushed to a public GitHub repository is turned off
at once, and the admins of the app's company (up to 10) get an email with the subject "An Exayard API key was found
in public and turned off". A key that is already revoked gets no second email.