Authenticate
This guide walks you through obtaining an OAuth2 access token and using it to authorize requests against the Protime API.
Before you begin
- Obtain your client_id and client_secret from Protime.
- Know your tenant name (the subdomain of your myProtime environment, e.g.
acmefromhttps://acme.myprotime.eu). - Know your environment URL:
myprotime.eu(production) ormyprotimesandbox.eu(sandbox). - Identify the OAuth2 scopes your integration requires, and confirm which scopes your credentials are entitled to. See OAuth2 scope model for background.
scope parameter is strongly recommended. It is not required, but a token carrying every entitled scope grows large and violates least-privilege principles.https://{Host}{path} – for example, Host: acme.myprotime.eu with path /connector/protimeapi/api/v1/clockings produces https://acme.myprotime.eu/connector/protimeapi/api/v1/clockings.OAuth2 client credentials flow
sequenceDiagram
participant Client as Your Application
participant Auth as Authentication Server
participant API as Protime API
Client->>Auth: POST /connect/token
Note over Client,Auth: grant_type=client_credentials<br/>client_id=xxx<br/>client_secret=xxx<br/>scope=xxx
Auth-->>Auth: Validate credentials
Auth-->>Client: Access Token (JWT)<br/>expires_in: XXXX seconds
Client->>API: API Request
Note over Client,API: Authorization: Bearer {token}
API-->>API: Validate token
API-->>Client: API Response (200 OK)
Note over Client,API: Token valid for XX minutes
Get an access token
Request an access token from the token endpoint:
https://authentication.<environmentURL>/tenants/<tenantName>/connect/token
Host: authentication.<environmentURL>
Content-Type: application/x-www-form-urlencodedInclude the following form fields in the request body:
grant_type=client_credentials
client_id=<your client id>
client_secret=<your client secret>
scope=connector-protimeapi-clockings.read connector-protimeapi-clockings.writeA successful response returns the token and its lifetime:
{
"access_token": "eyJ...Uc",
"expires_in": 1800,
"token_type": "Bearer",
"scope": "connector-protimeapi-clockings.read connector-protimeapi-clockings.write"
}The expires_in value is in seconds. Tokens are issued per tenant.
Use the access token
Set the Authorization header on every API request:
GET /connector/protimeapi/api/v1/clockings?filter=person%20in%20(1,2,3) HTTP/1.1
Host: <tenant>.myprotime.eu
Authorization: Bearer eyJ...Uc
User-Agent: YourService/v1 (YourCompany)Best practices
Reuse tokens
Reuse the same token for multiple requests instead of requesting a new token per call. Generating a token on every request may trigger rate limiting.
If you receive a 401 Unauthorized response, your token has most likely expired. Request a fresh token and retry. If a fresh token is rejected as well, see Troubleshoot token requests.
Narrow your scopes
Request only the scopes your integration actually needs.
scope=connector-protimeapi-clockings.read connector-protimeapi-clockings.writeIf your integration needs access to many collections and your credentials are entitled to them, use the general scopes connector-protimeapi-all.read and connector-protimeapi-all.write instead of listing every per-collection scope. See the OAuth2 scope model for details.
connector-protimeapi-all.read / connector-protimeapi-all.write and must list their per-collection scopes explicitly.Available scopes are listed per endpoint in the Swagger UI.
Troubleshoot token requests
| Response | Meaning | Resolution |
|---|---|---|
400 Bad Request – invalid_scope |
The request asked for at least one scope the client credentials are not entitled to, or a scope name is misspelled. | Compare the requested scopes against the scopes your credentials were issued with, and check the spelling against the scope reference. Ask the issuer of your credentials which scopes they carry. |
400 Bad Request – invalid_client |
The client_id / client_secret combination is wrong, or the credentials belong to another tenant. |
Verify the credentials and the tenant in the token URL. |
401 Unauthorized on an API call |
The token is missing, expired, invalid, or does not carry the scope the endpoint requires. | Request a fresh token. If it still fails, add the endpoint’s scope to the token request – if your credentials are entitled to it. |
403 Forbidden on an API call |
The token is valid but access to the resource is not granted. | Check the scope the endpoint documents and the tenant the token was issued for. |
invalid_scope rejects the whole token request. No token is issued, not even for the scopes that were valid. Remove the unentitled scope and request again.Related
- Authentication reference – token endpoint specification and OIDC discovery
- OAuth2 scope model – how scope naming works
- General specs reference – required headers and URI conventions