Authentication and scopes
A key is your integration's username and password. This guide explains the exchange in plain words, what each scope allows, and the handful of rules that keep keys safe.
Client credentials in plain words
Your integration never sends the key on a normal request. It sends the key once to the token endpoint and receives a signed access token that expires after 15 minutes. Each real request carries Authorization: Bearer <access_token>. Services validate the token locally, in memory, so there is no extra network hop per call, and the key itself stays on your side.
POST /api/public/v1/oauth/tokenwith the Client ID and secret: HTTP Basic (clientId:secret), or form fieldsgrant_type=client_credentials,client_id,client_secret.- Keep the
access_tokenfor up toexpires_inseconds (900). - Send
Authorization: Bearer …on every call. - On 401, or when the token is about to expire, go back to step 1.
Authorization: Bearer eyJhbGciOiJIUzI1NiIs…There is no refresh token and no user login. A key belongs to the company and acts with exactly the scopes it was created with.
Scopes
A scope names one capability. Each endpoint requires one scope; the reference shows it on every operation, and a token without it gets 403 insufficient_scope naming the scope that is missing.
| Scope | Permission | Kind | What it allows |
|---|---|---|---|
attendance.record | 86 | machine | Record clock events and completed shifts; set employee external ids |
attendance.read | 47 | human | Read time entries |
attendance.reports | 49 | human | Reserved for attendance reports; no endpoint yet |
employees.read | 52 | human | List employees |
leave.read | 72 | human | Reserved for leave data; no endpoint yet |
Machine scopes exist only for integrations: attendance.record cannot be assigned to a person in the roles editor, and any administrator who manages keys can grant it. Human scopes mirror a permission a person can hold, and a key can only receive one from a creator who holds that permission, or from a super admin. The number is the underlying permission id; it appears in the /me response and in 403 details.
People's own tokens
A person's HourSquare session token also works on the public API, for the operations their own permissions cover: someone who can view time tracking in the Hub can call GET /time-entries with their token, and /me reports "principal": "user" for them. That is what the interactive reference uses when you open it from the Hub. For anything automated, create a key: it does not depend on a person staying employed, and it is listed, rotated and revoked in one place.
Revocation and rotation
Revoking a key stops new tokens immediately. A token issued before the revoke keeps working until it expires, so there is a window of up to 15 minutes. If a secret leaked, treat that window as live and rotate anything else that shared it.
Rotate replaces a key with a new one under the same name and scopes. The old secret keeps working for 24 hours so you can deploy the new one without downtime; after that only the new key is accepted. An expiry date set on the old key carries over to the replacement.
Security rules
- Never put the key or a token in a URL or query string. They end up in logs, proxies and browser history.
- Never ship a key inside a browser page or a mobile app. Public routes send no CORS headers, so a browser call fails by design; put the key behind your own server.
- Give each integration its own key with the smallest scope set that works, and record where it is stored in the key's note.
- Set an expiry on anything temporary, and restrict the allowed IP ranges when the caller has fixed addresses.
- Rotate when in doubt. A rotation costs nothing while the old key stays valid for 24 hours.
- Watch the Last used column in the Hub: a key that has not been used for months is a key you can revoke.
Keys have a recognisable shape, hsq_ plus an 8-character id plus a secret, so a secret scanner can be configured to catch one in a repository.