Authentication
The Bonusly API accepts two credential types. You'll almost
always want a Personal Access Token (PAT). OAuth exists for
multi-user apps with a login flow (and for agentic integrations
via the Bonusly MCP server).
| Credential | Use case | Lifespan | Scopes |
|---|---|---|---|
| Personal Access Token (PAT) | Scripts, server-to-server jobs, SCIM, Digital Signage, most integrations | Up to 365 days; you choose at creation time | Fine-grained per resource |
Personal Access Tokens
PATs are bearer tokens created by a company admin from the
Company → Integrations → API & Tokens page.
Creating a token
- Sign in as a Global or Tech admin.
- Go to Profile Settings → API Tab or Company → Integrations → API & Tokens (if you're a Bonusly admin).
- Click Create token.
- Fill in:
- Name — anything memorable; this is how you'll
identify the token in the listing later. - Expiration — number of days, up to 365. Hard maximum,
no exceptions. - Scopes — pick the minimum set the integration needs.
Bonusly hides scopes your admin role can't grant.
- Name — anything memorable; this is how you'll
- Click Create. The token string is shown once —
copy it before closing the dialog. We store only a hash, so a
lost token can't be recovered; you'd have to create a new one.
Tip: create one PAT per integration. If a vendor changes
or a token leaks, you can revoke that one token without
disrupting anything else.
Sending a PAT on a request
Pass the token in the standard Authorization: Bearer … header:
curl https://bonus.ly/api/public/whoami \
-H "Authorization: Bearer YOUR_TOKEN_HERE"If your integration only supports an access_token=… query
parameter, that works too — but we recommend the header form
because query parameters can leak into HTTP server logs.
curl "https://bonus.ly/api/public/whoami?access_token=YOUR_TOKEN_HERE"Scopes
Scopes are the read/write/administer permissions you ask for at
creation time. They're grouped by resource family (users,
recognitions, awards, finance, company, analytics, uploads,
etc.) with a read, write, or administer flavor depending
on what you need. Pick the minimum set the integration actually
needs — adding the administer flavor to a resource that only
needs read is unnecessary blast radius if the token ever
leaks.
The set of scopes you can grant is gated by your admin role.
Global admins can grant any scope; Tech admins can grant a
subset. The full, authoritative list is shown to you in the
create-token modal with anything your role can't grant
already filtered out — you can't accidentally request a scope
the API will then refuse.
At request time, the API rejects calls whose token doesn't
include the scope the endpoint requires.
Finding the scope an endpoint needs: every endpoint's
documentation page in the API reference lists the scope (or
scopes) it requires under the Authorization heading. If
you're not sure what to ask for when creating a token, open
the docs for the endpoints your integration will call and
collect the union of their required scopes.
Expiration and renewal
Every PAT expires — there is no perpetual token. We email the
token owner twice before expiration:
- 30 days out — heads-up, plan a renewal.
- 7 days out — final reminder.
When a token expires it stops working. To renew:
- Create a fresh token from the API & Tokens page with the
same scopes (use the old token's name as a reference). - Update the integration's stored credential with the new
token. - Revoke the old, now-expired row from the table to keep things
tidy.
There's no auto-rotation; renewals are a deliberate human
action.
Revoking a token
Revocation is immediate. Find the row in the API & Tokens
table and click Revoke. The next request bearing that
token gets a 401 Unauthorized.
Bonusly will also revoke PATs automatically in one situation:
7 days after a company subscription is canceled, if the
cancellation hasn't been reversed. If you resubscribe inside that
7-day window, nothing happens to your tokens. If you resubscribe
after the auto-revocation, you'll need to create fresh tokens.
Sample request
A canonical authenticated call:
curl https://bonus.ly/api/public/whoami \
-H "Authorization: Bearer YOUR_TOKEN_HERE" \
-H "Accept: application/json"Response (truncated):
{
"success": true,
"message": "authenticated",
"company": { "id": "abc123", "name": "Acme Corp" },
"application": { "id": "def456", "name": "My Integration" },
"scopes": ["user:read", "awards:read"],
"user": null
}Errors you might see
| Status | What it means | What to do |
|---|---|---|
401 Unauthorized | The bearer is missing, malformed, or unknown. | Confirm the Authorization header includes Bearer and a non-empty token. |
401 Unauthorized | The bearer is expired, revoked, or the owner was deactivated. | Create a new token. |
403 Forbidden | The bearer is valid but doesn't carry the scope required by the endpoint. | Create a new token with the right scope, or use a different endpoint. |
429 Too Many Requests | The company has exceeded the rate limit for this operation. | Honor the Retry-After header before retrying. See Rate limits on the Getting started page; limits vary by operation and can be raised on request. |
For the full picture of error envelopes and rate-limit headers,
see Getting started.
See also
- Getting started — from zero to your
first API call. - The API reference in the sidebar — every endpoint shows the
scope it requires.