Your first API call
The shortest route to a working call with each TimeLog API: REST, Transactional and Reporting.
Pick the API you chose and follow its path. Each one ends at that API's own guide, where you continue.
Before you start
- Your base URL.
https://app{server-number}.timelog.com/{account}. See Find your base URL. - A credential for the API. See What you need and Authentication overview.
Make the call
GET /v1/user/me reads only the token's own user and changes nothing, so it is safe to call at any time.
export TIMELOG_TOKEN='<your-personal-access-token>'
curl https://app{server-number}.timelog.com/{account}/api/v1/user/me \
-H "Authorization: Bearer $TIMELOG_TOKEN" \
-H "Accept: application/json"
200 means the token is accepted, and the response is the user the token acts as. 401 means it is not: see
Troubleshooting 401 responses.
1. Get a token. Call GetToken on the Security service with a TimeLog user name and password:
POST /{account}/WebServices/Security/V1_2/SecurityServiceSecure.svc HTTP/1.1
Host: app{server-number}.timelog.com
Content-Type: text/xml; charset=utf-8
SOAPAction: "GetTokenRequest"
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:sec="http://www.timelog.com/api/tlp/v1_2">
<soapenv:Body>
<sec:GetToken>
<sec:user>{user name}</sec:user>
<sec:password>{password}</sec:password>
</sec:GetToken>
</soapenv:Body>
</soapenv:Envelope>
Check that ResponseState is Success, then keep Initials, Expires and Hash from Return.
2. Read with the token. Send the three values, unchanged, as the last parameter of a read, for example GetCustomersModifiedSincePaged:
POST /{account}/WebServices/CRM/V1_4/CRMServiceSecure.svc HTTP/1.1
Host: app{server-number}.timelog.com
Content-Type: text/xml; charset=utf-8
SOAPAction: "http://api.timelog.com/services/crm/1_4/ICRMService/GetCustomersModifiedSincePaged"
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:crm="http://api.timelog.com/services/crm/1_4"
xmlns:tok="http://www.timelog.com/api/tlp/v1_3">
<soapenv:Body>
<crm:GetCustomersModifiedSincePaged>
<crm:date>{date, e.g. 2026-10-01T00:00:00}</crm:date>
<crm:includeCustomers>true</crm:includeCustomers>
<crm:includeSuppliers>false</crm:includeSuppliers>
<crm:includeLeads>false</crm:includeLeads>
<crm:loadCustomFields>false</crm:loadCustomFields>
<crm:loadExternalKeys>false</crm:loadExternalKeys>
<crm:page>1</crm:page>
<crm:pageSize>100</crm:pageSize>
<crm:token>
<tok:Initials>{Initials from GetToken}</tok:Initials>
<tok:Expires>{Expires from GetToken, unchanged}</tok:Expires>
<tok:Hash>{Hash from GetToken}</tok:Hash>
</crm:token>
</crm:GetCustomersModifiedSincePaged>
</soapenv:Body>
</soapenv:Envelope>
The answer is HTTP 200 even when the call fails, so check ResponseState first.
Next: Try it with Bruno.
1. Check the credentials. ValidateCredentials answers true or false:
POST /{account}/Service.asmx HTTP/1.1
Host: app{server-number}.timelog.com
Content-Type: text/xml; charset=utf-8
SOAPAction: "http://www.timelog.com/ws/tlp/v4_4/ValidateCredentials"
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:tlp="http://www.timelog.com/ws/tlp/v4_4">
<soap:Body>
<tlp:ValidateCredentials>
<tlp:siteCode>{siteCode}</tlp:siteCode>
<tlp:apiID>{apiID}</tlp:apiID>
<tlp:apiPassword>{apiPassword}</tlp:apiPassword>
</tlp:ValidateCredentials>
</soap:Body>
</soap:Envelope>
2. Read a short list. GetCustomersShortList returns the account's customers as IDs and names:
POST /{account}/Service.asmx HTTP/1.1
Host: app{server-number}.timelog.com
Content-Type: text/xml; charset=utf-8
SOAPAction: "http://www.timelog.com/ws/tlp/v4_4/GetCustomersShortList"
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:tlp="http://www.timelog.com/ws/tlp/v4_4">
<soap:Body>
<tlp:GetCustomersShortList>
<tlp:siteCode>{siteCode}</tlp:siteCode>
<tlp:apiID>{apiID}</tlp:apiID>
<tlp:apiPassword>{apiPassword}</tlp:apiPassword>
<tlp:customerStatusID>-1</tlp:customerStatusID>
<tlp:accountManagerID>0</tlp:accountManagerID>
</tlp:GetCustomersShortList>
</soap:Body>
</soap:Envelope>
Next: Try it with Bruno.
Try it with Bruno
Transactional API collection
Every Transactional operation, ready to run, with the token handled for you.
Reporting API collection
Every Reporting method, grouped by entity, with the filters pre-filled.
If your first call fails
| API | How a failure looks | Where to look |
|---|---|---|
| REST | An HTTP error status, for example 401 | Errors |
| Transactional | HTTP 200 with ResponseState = Error or Invalid | Responses and errors |
| Reporting | HTTP 401 or 500, with the reason in tlp:Error | Responses and errors |