Authentication
How to authenticate to the TimeLog REST API with a bearer token, which user your requests act as, how to test a token, and how to troubleshoot 401 responses.
Overview
Every TimeLog REST API request must carry an access token in the Authorization header, as a bearer token:
Authorization: Bearer <your-token>
There is no anonymous access. A request without a valid token is rejected with 401 Unauthorized.
v1 and v2 use the same authentication: the same token works for both, and there is no version-specific scope or setting.
The token decides two things:
- Whether the request is accepted at all. The token must be valid, not expired, and carry the TimeLog API scope.
- Who the request acts as. Every request runs as the token's user. What you can read and change is what that user can read and change in TimeLog.
Personal access tokens
For an integration, the token is a personal access token (PAT). A personal access token belongs to the TimeLog user who generated it. Every request made with it acts as that user and is checked against that user's permissions.
Personal access tokens are generated at https://login.timelog.com/personaltoken.
Create a personal access token
Log in to TimeLog
Log in to your TimeLog site, https://app{server-number}.timelog.com/{account}, as the user the integration will act as.
Open the token page
Go to https://login.timelog.com/personaltoken.
Create the token
Click New Token, give the token a name that says which integration uses it, and set when it expires.
Copy the token
Click Save and copy the token value. Store it in your secret store right away.
You choose how long a token stays valid when you create it, up to a maximum of two years. Plan to replace it before
it expires: an expired token is rejected with 401.
Revoke or regenerate a token
On the same page:
- Revoke a token you no longer use, or one you suspect has been seen by someone else, so it cannot be used again.
- Regenerate a token to get a new value for it. Copy the new value; the integration must then use it.
Which user should own the token
Because a token acts as its user, the choice of user is a design decision for your integration:
- Actions are attributed to the token's user.
- Permissions are checked against the token's user. An operation the user is not allowed to perform fails, even if the token itself is valid. See Errors for the
403response. - If the user can no longer log in to TimeLog (inactive, locked or deleted), every request with the token is rejected with
401.
Tokens that are not tied to a user act as a system user. Prefer tokens tied to a user, so that actions are attributed to a person and permission-checked.
Base URL
Send requests to your TimeLog site, followed by /api/ and the API version:
https://app{server-number}.timelog.com/{account}/api/v1/...
https://app{server-number}.timelog.com/{account}/api/v2/...
| Placeholder | Meaning |
|---|---|
{server-number} | The number after app in your TimeLog address, for example 3 in https://app3.timelog.com. |
{account} | Your TimeLog account name, the same one you use to log in. It is the first path segment after the host name. |
If your browser shows https://app.timelog.com without a number, find your site URL in TimeLog under System Administration > Integrations and API > Reporting API settings, in the section Your TimeLog API URL. It follows the pattern https://app[X].timelog.com/[account name].
Make an authenticated request
Pass the token in the Authorization header on every request:
curl https://app{server-number}.timelog.com/{account}/api/v1/user/me \
-H "Authorization: Bearer $TIMELOG_TOKEN" \
-H "Accept: application/json"
Read the token from an environment variable or a secret store, as above. Do not paste it into scripts or commit it to source control.
Test your token
Before you build anything else, check the token with GET /v1/user/me.
It reads nothing but the token's own user and changes nothing, so it is safe to call at any time.
Call GET /v1/user/me
Send the request from Make an authenticated request with your token and your site's base URL.
Check the status code
200 means the token is accepted. 401 means it is not: see Troubleshooting 401 responses.
Check the user
The response is the user the token acts as. Confirm it is the user you expect. Keep UserID if your integration registers time for that user.
A successful response (abbreviated: some properties removed, e-mail redacted):
{
"Properties": {
"UserID": 1,
"ID": "1b9afd4f-5ea9-4447-94bf-2bfd7ce96a25",
"FirstName": "FirstName_Admin1",
"LastName": "LastName",
"IsActive": true,
"UserType": "Employee",
"Email": "<redacted>"
},
"Links": [
{ "Href": "https://app{server-number}.timelog.com/{account}/api/v1/user/me", "Rel": "self" }
]
}
The user is under Properties, as in every single-object response. See Response envelope.
The same request without a token:
{ "Message": "Authorization has been denied for this request." }
Troubleshooting 401 responses
A 401 Unauthorized response always has the same body, whatever the cause:
{ "Message": "Authorization has been denied for this request." }
This is not the regular error body with Code, Details and Parameters. Check the HTTP status before you parse the body. See Errors.
The body does not say which check failed. Work through the causes in order:
| Cause | What to check |
|---|---|
No Authorization header | The header is present and has the form Authorization: Bearer <token>. |
| Wrong or truncated token | The full token was copied, with no surrounding quotes, spaces or line breaks. |
| Wrong base URL | {server-number} and {account} match the URL of the TimeLog site the token belongs to. |
| Expired or revoked token | Generate a new token and try again. |
| Token without the TimeLog API scope | The token was issued for the TimeLog API. A personal access token generated as described above carries it. |
| The token's user cannot log in | The user is still active in TimeLog and is not locked or deleted. A valid token for such a user is rejected. |
Retrying a 401 with the same token does not help. Fix the cause, then retry once. If the second attempt also returns 401, stop and report an authentication problem instead of retrying in a loop.
Security hygiene
A personal access token gives the same API access as its user. Treat it like a password.
- Store tokens as secrets. Keep them in your platform's secret store or an environment variable, never in source code, logs, or URLs.
- Use one token per integration. If one integration is compromised or retired, you can revoke its token without breaking the others.
- Revoke tokens you no longer use. A forgotten token still works as long as it is valid.
- Choose the token's user deliberately. Give the integration a user with only the permissions it needs.
- Do not log request headers. The token travels in the
Authorizationheader on every request.
Rate limits
TimeLog has not published hard rate limits. Usage is monitored, and TimeLog contacts the account before limiting it. See Usage and change policy and Rate limits and known limitations.