Get started
Quickstart
Five minutes from nothing to your first response. You need a ClockLap workspace and to be an owner or admin (anyone who can manage integrations).
1. Create an API key#
- Open Developers settings
In the console, go to Settings → Developers → API keys and click Create key.
- Name it and pick its access
Name it after what will use it, for example “Payroll export”. Tick only the access it needs, such as Read time entries and timesheets. Pick Test to try things on sample data first.
- Copy the key
It looks like
tt_live_ca_9fK2…and is shown only once. Store it in your tool's secret settings or a password manager.
2. Make your first request#
Put the key in an environment variable, then list your workspace's locations. Pick your region so the examples use the right address. Your key shows it: tt_live_ca_… is Canada, tt_live_us_… is the United States.
export CLOCKLAP_API_KEY="tt_live_ca_9fK2…"
curl https://ca-api.clocklap.com/v1/locations \
-H "Authorization: Bearer $CLOCKLAP_API_KEY"// Node.js 18 or later (fetch is built in)
const res = await fetch('https://ca-api.clocklap.com/v1/locations', {
headers: { Authorization: `Bearer ${process.env.CLOCKLAP_API_KEY}` },
});
if (!res.ok) throw new Error((await res.json()).detail);
const { data } = await res.json();
console.log(data.map((l) => l.name));# pip install requests
import os, requests
res = requests.get(
"https://ca-api.clocklap.com/v1/locations",
headers={"Authorization": f"Bearer {os.environ['CLOCKLAP_API_KEY']}"},
)
res.raise_for_status()
print([l["name"] for l in res.json()["data"]])You get back JSON with a data list:
{
"data": [
{
"id": "loc_01J9Q…",
"type": "site",
"name": "Toronto Warehouse",
"parent_id": "loc_01J9P…",
"address": "120 Industrial St, Toronto",
"timezone": null,
"people": 14,
"on_site": 9
}
]
}Locations are regions, sites and zones; build the tree from parent_id. A timezone of null means the site uses its region's or the workspace's.
3. Read some hours#
Now fetch last week's shifts. Times are ISO 8601 with an offset; each entry also carries its site's timezone and local_date.
curl -G https://ca-api.clocklap.com/v1/time-entries \
-H "Authorization: Bearer $CLOCKLAP_API_KEY" \
--data-urlencode "from=2026-10-19T00:00:00-04:00" \
--data-urlencode "to=2026-10-26T00:00:00-04:00" \
-d limit=100const q = new URLSearchParams({ from: '2026-10-19T00:00:00-04:00', to: '2026-10-26T00:00:00-04:00', limit: '100' });
const res = await fetch(`https://ca-api.clocklap.com/v1/time-entries?${q}`, {
headers: { Authorization: `Bearer ${process.env.CLOCKLAP_API_KEY}` },
});
const { data, has_more, next_cursor } = await res.json();res = requests.get(
"https://ca-api.clocklap.com/v1/time-entries",
headers={"Authorization": f"Bearer {os.environ['CLOCKLAP_API_KEY']}"},
params={"from": "2026-10-19T00:00:00-04:00", "to": "2026-10-26T00:00:00-04:00", "limit": 100},
)
page = res.json() # page["data"], page["has_more"], page["next_cursor"]More than 100? Pass next_cursor back as cursor until has_more is false. See pagination.