Your First API Call
Prerequisites
Before we begin, make sure you have the following:
- A tenant name for your Protime environment (e.g.
acmefromhttps://acme.myprotime.eu) - An OAuth2 client_id and client_secret provided by Protime
- A tool for making HTTP requests (e.g. curl, Postman, or your programming language of choice)
- At least one person with clocking data in your Protime environment
Step 1: Obtain an access token
We’ll start by requesting an access token from the Protime authentication server. This token grants us permission to read clockings.
Request
https://authentication.<environmentURL>/tenants/<tenantName>/connect/token
Replace <environmentURL> with myprotime.eu for production or myprotimesandbox.eu for sandbox. Replace <tenantName> with your tenant name.
POST /tenants/acme/connect/token HTTP/1.1
Host: authentication.myprotime.eu
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials&client_id=your-client-id&client_secret=your-client-secret&scope=connector-protimeapi-clockings.readVerify: The response contains an access_token and an expires_in value indicating how many seconds the token remains valid.
{
"access_token": "eyJ...Uc",
"expires_in": 1800,
"token_type": "Bearer",
"scope": "connector-protimeapi-clockings.read"
}We’ll use this access_token in the next step. The token is valid for 1800 seconds (30 minutes), so we should reuse it for multiple requests rather than requesting a new token each time. When the token expires, the API returns a 401 Unauthorized response, and we need to request a fresh token by repeating this step.
Tip
Reuse a token for as many calls as possible within its lifetime. Requesting a new token for every single API call may trigger rate limiting.
Step 2: Retrieve clockings
Now let’s fetch clockings for a specific person during January 2026. We’ll pass the access token in the Authorization header as a Bearer token. The clockings endpoint requires at least a date filter, and we can optionally filter by person to narrow the results.
Request
https://<tenant>.myprotime.eu/connector/protimeapi/api/v1/clockings?filter=person in (1) and date ge '2026-01-01' and date le '2026-01-31'
GET /connector/protimeapi/api/v1/clockings?filter=person%20in%20(1)%20and%20date%20ge%20'2026-01-01'%20and%20date%20le%20'2026-01-31' HTTP/1.1
Host: acme.myprotime.eu
Authorization: Bearer eyJ...UcVerify: You should see a 200 OK response with a value array containing clocking objects.
{
"value": [
{
"changeVersion": "0000090200004BD0000A",
"id": 18601,
"calculatedTimeOfDayInMinutes": 510,
"isGenerated": false,
"status": "Active",
"person": {
"id": 1
},
"date": "2026-01-02",
"timeOfDayInMinutes": 510,
"terminal": {
"id": 42
},
"kind": "InOut"
},
{
"changeVersion": "0000090200004BD0000B",
"id": 18602,
"calculatedTimeOfDayInMinutes": 1020,
"isGenerated": false,
"status": "Active",
"person": {
"id": 1
},
"date": "2026-01-02",
"timeOfDayInMinutes": 1020,
"terminal": {
"id": 42
},
"kind": "InOut"
}
],
"nextLink": null
}In this example, the two clocking objects represent a clock-in at 08:30 (510 minutes since midnight) and a clock-out at 17:00 (1020 minutes since midnight) for person 1 on January 2nd. If the response contains more data than fits on a single page, a nextLink will appear instead of null. We’ll look at that next.
Step 3: Understand the response
Let’s break down the key fields in each clocking object:
| Field | Meaning |
|---|---|
changeVersion |
A version string used for ordering changes; we’ll use this in delta tracking later |
id |
Unique identifier for this clocking |
calculatedTimeOfDayInMinutes |
The calculated time of day in minutes since midnight, after any system adjustments |
isGenerated |
Whether this clocking was automatically generated by the system |
status |
Whether the clocking is Active or Deleted (soft-deleted clockings remain visible) |
person.id |
The internal ID of the employee who clocked |
date |
The date of the clocking in YYYY-MM-DD format |
timeOfDayInMinutes |
Time expressed as minutes since midnight. For example, 510 means 08:30 (8 hours x 60 + 30 minutes) |
kind |
The type of clocking: InOut, Reason, Activity, or ActivityEnd |
Converting timeOfDayInMinutes to a clock time
The timeOfDayInMinutes field represents minutes since midnight. To convert it to hours and minutes, we divide by 60:
510minutes = 8 hours and 30 minutes = 08:301020minutes = 17 hours and 0 minutes = 17:00
In code, this looks like: hours = timeOfDayInMinutes / 60, minutes = timeOfDayInMinutes % 60.
Pagination with nextLink
When the result set is larger than a single page, the response includes a nextLink field. To retrieve the next page, we make a GET request to the base URL combined with the nextLink path:
https://<tenant>.myprotime.eu{nextLink}
We keep following nextLink values until the field is null, which indicates we have reached the last page. It is important to always check for nextLink – even if a page returns an empty value array, a nextLink may still be present, meaning there are more pages to fetch.
Error handling
If something goes wrong, the API returns an error object with a code and a message:
{
"error": {
"code": "BadRequest",
"message": "The request was invalid"
}
}Common error codes at this stage include 401 (expired or missing token), 400 (missing or malformed filter), and 429 (too many requests). If you receive a 401, go back to Step 1 and request a new access token.
What you’ve accomplished
- Authenticated with the Protime API using OAuth2 client credentials
- Retrieved a filtered list of clockings for a specific person and date range
- Understood the structure of a clocking response, including key fields and pagination
Next steps
- Your first clocking integration – learn how to create clockings and track changes with delta
- Real-time sync with webhooks – set up webhooks for push-based notifications
- How to authenticate – deeper guidance on token management and scopes
- How to fetch resources – filtering, pagination, and external references
- Clockings reference – full endpoint and property documentation
Related concepts
- Architecture overview – how the connector layer sits between integrators and the Protime platform
- Multi-tenancy – why every URL and token is scoped to a single tenant
- OAuth2 scope model – how scopes like
connector-protimeapi-clockings.readcontrol access