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, Postman or SoapUI.
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, Postman or SoapUI.
Try it without code
REST API
The playground on every operation page, or Postman.
Transactional API
A ready-to-run Bruno collection with the token handled for you, or Postman and SoapUI.
Reporting API
A ready-to-run Bruno collection with the filters pre-filled, or Postman and SoapUI.
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 |