List the hourly rates a task's contract offers
Lists the active hourly rates of a task's contract (plus one rate in use), cheapest first, for choosing an allocation's rate.
Resolves the task's contract and returns its ACTIVE contract hourly rates, ordered by amount then name, plus the rate given in suggestedHourlyRateId even when inactive (only if it belongs to the same contract) — so a rate already in use stays selectable. Unpaged. Amounts are in the rate's price-group currency, which is not returned. A contract with no matching rate answers 200 with the body null instead of an empty list.
Use it to:
- Offer the rate choices when allocating a person to a task (default = SuggestedHourlyRateId from employee-unallocated)
Not for:
- Full rate records with currency, GUID and product number →
GET /v1/contract-hourly-rate
Behaviour:
- Idempotent.
- Safe to retry.
- Consistency: immediate
Call first: GET /v2/projects/{projectId}/employee-unallocated
Next: POST /v1/task/{taskID}/allocation
See also: GET /v1/contract-hourly-rate, GET /v2/projects/{projectId}/employee-allocation
Not yet documented: description; examples.
curl -X GET "https://app3.timelog.com/your-account/api/v2/contract-hourly-rates/dropdown-content?taskId=123&suggestedHourlyRateId=0" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_TOKEN"
import requests
import json
url = "https://app3.timelog.com/your-account/api/v2/contract-hourly-rates/dropdown-content?taskId=123&suggestedHourlyRateId=0"
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/v2/contract-hourly-rates/dropdown-content?taskId=123&suggestedHourlyRateId=0", {
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/v2/contract-hourly-rates/dropdown-content?taskId=123&suggestedHourlyRateId=0", 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/v2/contract-hourly-rates/dropdown-content?taskId=123&suggestedHourlyRateId=0')
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
{
"Entities": [
{
"Properties": {
"ContractHourlyRateID": 123,
"ProjectSubContractID": 123,
"Name": "John Doe",
"Amount": 3.14,
"Type": "Standard"
},
"Links": [
{
"Href": "example_string",
"Rel": "example_string"
}
],
"Actions": [
{}
]
}
],
"Links": [
{
"Href": "example_string",
"Rel": "example_string"
}
]
}
{
"error": "Unauthorized",
"message": "Authentication required. Please provide a valid API token",
"code": 401
}
{
"error": "Not Found",
"message": "The requested resource was not found",
"code": 404
}
{
"error": "Internal Server Error",
"message": "An unexpected error occurred on the server",
"code": 500,
"requestId": "req_1234567890"
}
/v2/contract-hourly-rates/dropdown-content
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.
> Not yet documented: how to obtain a token.
> Not yet documented: token lifetime.
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.
> Not yet documented: how to obtain a token.
> Not yet documented: token lifetime.Task whose contract's rates are listed. Omitted → 404 (captured); unknown → 500.
A rate to include even if inactive (ignored when it is on another contract); 0 = none.
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.
Not yet documented: how to obtain a token.
Not yet documented: token lifetime.
Query Parameters
Task whose contract's rates are listed. Omitted → 404 (captured); unknown → 500.
A rate to include even if inactive (ignored when it is on another contract); 0 = none.
Responses
Omitted (not []) when the list is empty.