Search a customer's projects for expense or travel registration
Lists one customer's projects the caller can book an expense or mileage on — allocated projects by recent use, or (searchAll) every active project by name.
The project step of a customer → project picker in an expense or mileage client. Scoping, ordering, the searchAll account-feature gate and the field meanings are those of GET /v1/project-header/search-for-expense-travel-registration-order-by-recent-registration, restricted to customerID. Customer is always filled on every entity.
Use it to:
- Customer → project picker in an expense app (customer from
GET /v1/customer/search-for-expense-travel-registration-order-by-recent-registration)
Behaviour:
- Idempotent.
- Safe to retry.
- Consistency: eventual
Call first: GET /v1/customer/search-for-expense-travel-registration-order-by-recent-registration
Next: POST /v1/project-header/employee-expense, POST /v1/project-header/mileage-registration
See also: GET /v1/project-header/search-for-expense-travel-registration-order-by-recent-registration
curl -X GET "https://app3.timelog.com/your-account/api/v1/project-header/search-for-expense-travel-registration-by-customer-id-order-by-recent-registration?customerID=123&searchText=%22%22&searchAll=false&$page=1&$pagesize=10" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_TOKEN"
import requests
import json
url = "https://app3.timelog.com/your-account/api/v1/project-header/search-for-expense-travel-registration-by-customer-id-order-by-recent-registration?customerID=123&searchText=%22%22&searchAll=false&$page=1&$pagesize=10"
headers = {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_API_TOKEN"
}
response = requests.get(url, headers=headers)
print(response.json())
const response = await fetch("https://app3.timelog.com/your-account/api/v1/project-header/search-for-expense-travel-registration-by-customer-id-order-by-recent-registration?customerID=123&searchText=%22%22&searchAll=false&$page=1&$pagesize=10", {
method: "GET",
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_API_TOKEN"
}
});
const data = await response.json();
console.log(data);
package main
import (
"fmt"
"net/http"
)
func main() {
req, err := http.NewRequest("GET", "https://app3.timelog.com/your-account/api/v1/project-header/search-for-expense-travel-registration-by-customer-id-order-by-recent-registration?customerID=123&searchText=%22%22&searchAll=false&$page=1&$pagesize=10", nil)
if err != nil {
panic(err)
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer YOUR_API_TOKEN")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println("Response Status:", resp.Status)
}
require 'net/http'
require 'json'
uri = URI('https://app3.timelog.com/your-account/api/v1/project-header/search-for-expense-travel-registration-by-customer-id-order-by-recent-registration?customerID=123&searchText=%22%22&searchAll=false&$page=1&$pagesize=10')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Get.new(uri)
request['Content-Type'] = 'application/json'
request['Authorization'] = 'Bearer YOUR_API_TOKEN'
response = http.request(request)
puts response.body
{
"Properties": {
"TotalRecord": "example_string",
"TotalPage": "example_string",
"PageNumber": "example_string"
},
"Entities": [
{
"Properties": {
"ProjectID": 123,
"ID": "123e4567-e89b-12d3-a456-426614174000",
"Name": "John Doe",
"No": "example_string",
"ExpenseIsBillable": "null",
"CustomerID": 123,
"Customer": {
"CustomerID": 123,
"ID": "123e4567-e89b-12d3-a456-426614174000",
"Name": "John Doe",
"No": "example_string",
"DefaultMileageDistance": 25,
"CustomerStatusID": 123,
"VATNo": "example_string",
"OrganizationNo": "example_string"
},
"MainContractId": 123
},
"Links": [
{
"Href": "example_string",
"Rel": "example_string"
}
],
"Actions": [
{}
]
}
],
"Links": [
{
"Href": "example_string",
"Rel": "example_string"
}
]
}
{
"Message": "Authorization has been denied for this request."
}
{
"Code": 103,
"Message": "…",
"Details": [],
"Parameters": "…",
"Url": "https://app{server-number}.timelog.com/{account}/api/v1/project-header/search-for-expense-travel-registration-by-customer-id-order-by-recent-registration"
}
{
"Message": "No HTTP resource was found that matches the request URI 'https://app{server-number}.timelog.com/{account}/api/v1/project-header/search-for-expense-travel-registration-by-customer-id-order-by-recent-registration'.",
"MessageDetail": "No action was found on the controller 'ProjectHeader' that matches the request."
}
{
"Code": 100,
"Message": "Unknown error occur in system, please contact system administrator.",
"Details": [],
"Parameters": "…",
"Url": "https://app{server-number}.timelog.com/{account}/api/v1/project-header/search-for-expense-travel-registration-by-customer-id-order-by-recent-registration"
}
/v1/project-header/search-for-expense-travel-registration-by-customer-id-order-by-recent-registration
Target server for requests. Edit to use your own host.
OAuth 2.0 bearer token, sent as Authorization: Bearer <token>. JWT and reference tokens are both accepted. The token must carry the required scope (default tlp).
The token's sub claim is the acting user. A token WITHOUT sub (client-credentials) acts as the system service user. If the sub user cannot log in (inactive, locked, deleted), the request is rejected with 401 — it is no longer let through without a user.
Authorization: Bearer <token>. JWT and reference tokens are both accepted. The token must carry the required scope (default tlp).
The token's sub claim is the acting user. A token WITHOUT sub (client-credentials) acts as the system service user. If the sub user cannot log in (inactive, locked, deleted), the request is rejected with 401 — it is no longer let through without a user.Customer whose projects are returned. Omitted → 404 (no action matched). Unknown ID → empty list.
Filters on ProjectHeaderRead.CustomerID (eq).
Substring matched against project name and number (LIKE '%text%'). Empty = no text filter.
Filters on ProjectHeaderRead.Name | ProjectHeaderRead.No (contains).
true = all active non-template projects of the customer, ordered by name. Needs the account feature EnableAllEmployeesRegisterOnAllActiveProjects.
Page number.
Page size. No maximum enforced in the API layer.
Request Preview
Response
Response will appear here after sending the request
Authentication
Bearer token. OAuth 2.0 bearer token, sent as Authorization: Bearer <token>. JWT and reference tokens are both accepted. The token must carry the required scope (default tlp).
The token's sub claim is the acting user. A token WITHOUT sub (client-credentials) acts as the system service user. If the sub user cannot log in (inactive, locked, deleted), the request is rejected with 401 — it is no longer let through without a user.
Query Parameters
Customer whose projects are returned. Omitted → 404 (no action matched). Unknown ID → empty list.
Filters on ProjectHeaderRead.CustomerID (eq).
Substring matched against project name and number (LIKE '%text%'). Empty = no text filter.
Filters on ProjectHeaderRead.Name | ProjectHeaderRead.No (contains).
true = all active non-template projects of the customer, ordered by name. Needs the account feature EnableAllEmployeesRegisterOnAllActiveProjects.
Page number.
Page size. No maximum enforced in the API layer.
Responses
Paging values. They are returned as STRINGS, for example "TotalRecord": "12".
Omitted (not []) when the list is empty.