Update a customer
Changes an existing customer's master data, addressed by CustomerID in the body.
Updates name, number, contact data, owners, status, industry and addresses. Invoice settings cannot be changed here. The update is neither a full replace nor a patch: eleven text fields are CLEARED when omitted, the rest are left unchanged (see CustomerUpdate). Send the current value of every text field you do not want to lose. There is no validation of the body.
Behaviour:
- Idempotent.
- Safe to retry.
- Side effect: Saves the customer and its (unchanged) invoice settings; saves its external keys.
- Side effect: A changed CustomerStatusID: an extra save of the customer before the main save (CMGR.ChangeCustomerStatus → UpdatePrivate).
- On failure: When CustomerStatusID changes, the status AND every group-A field and CurrencyID already mapped (Name, CustomerNo, NickName, OrganizationNo, Phone, Fax, Email, Website, VatNo, CreditorID, InvoicingName) are saved even if the main update then fails with 403 or 500. That save raises no CustomerUpdate event.
- Changes are visible to the next read immediately.
Call first: GET /v1/customer/{customerID}, GET /v1/customer
Next: GET /v1/customer/{customerID}
See also: POST /v1/customer/create
Not yet documented: examples (success).
curl -X PUT "https://app3.timelog.com/your-account/api/v1/customer/update" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-d '{
"CustomerID": 123,
"Name": "John Doe",
"CustomerNo": "example_string",
"NickName": "John Doe",
"OrganizationNo": "example_string",
"Phone": "+1-555-0123",
"Fax": "example_string",
"Email": "user@example.com",
"Website": "example_string",
"VatNo": "example_string",
"CreditorID": "example_string",
"InvoicingName": "John Doe",
"CurrencyID": 123,
"CustomerStatusID": 123,
"CustomerSince": "2024-12-25T10:00:00Z",
"PrimaryKAMID": 123,
"SecondaryKAMID": 123,
"IndustryID": 123,
"UseInvoicingAddress": true,
"CountryID": 123,
"Address": "123 Main St",
"Address2": "123 Main St",
"Address3": "123 Main St",
"ZipCode": "example_string",
"City": "New York",
"State": "example_string",
"InvoicingAddressCountryID": 123,
"InvoicingAddress": "123 Main St",
"InvoicingAddress2": "123 Main St",
"InvoicingAddress3": "123 Main St",
"InvoicingAddressZipCode": "123 Main St",
"InvoicingAddressCity": "123 Main St",
"InvoicingAddressState": "123 Main St"
}'
import requests
import json
url = "https://app3.timelog.com/your-account/api/v1/customer/update"
headers = {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_API_TOKEN"
}
data = {
"CustomerID": 123,
"Name": "John Doe",
"CustomerNo": "example_string",
"NickName": "John Doe",
"OrganizationNo": "example_string",
"Phone": "+1-555-0123",
"Fax": "example_string",
"Email": "user@example.com",
"Website": "example_string",
"VatNo": "example_string",
"CreditorID": "example_string",
"InvoicingName": "John Doe",
"CurrencyID": 123,
"CustomerStatusID": 123,
"CustomerSince": "2024-12-25T10:00:00Z",
"PrimaryKAMID": 123,
"SecondaryKAMID": 123,
"IndustryID": 123,
"UseInvoicingAddress": true,
"CountryID": 123,
"Address": "123 Main St",
"Address2": "123 Main St",
"Address3": "123 Main St",
"ZipCode": "example_string",
"City": "New York",
"State": "example_string",
"InvoicingAddressCountryID": 123,
"InvoicingAddress": "123 Main St",
"InvoicingAddress2": "123 Main St",
"InvoicingAddress3": "123 Main St",
"InvoicingAddressZipCode": "123 Main St",
"InvoicingAddressCity": "123 Main St",
"InvoicingAddressState": "123 Main St"
}
response = requests.put(url, headers=headers, json=data)
print(response.json())
const response = await fetch("https://app3.timelog.com/your-account/api/v1/customer/update", {
method: "PUT",
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_API_TOKEN"
},
body: JSON.stringify({
"CustomerID": 123,
"Name": "John Doe",
"CustomerNo": "example_string",
"NickName": "John Doe",
"OrganizationNo": "example_string",
"Phone": "+1-555-0123",
"Fax": "example_string",
"Email": "user@example.com",
"Website": "example_string",
"VatNo": "example_string",
"CreditorID": "example_string",
"InvoicingName": "John Doe",
"CurrencyID": 123,
"CustomerStatusID": 123,
"CustomerSince": "2024-12-25T10:00:00Z",
"PrimaryKAMID": 123,
"SecondaryKAMID": 123,
"IndustryID": 123,
"UseInvoicingAddress": true,
"CountryID": 123,
"Address": "123 Main St",
"Address2": "123 Main St",
"Address3": "123 Main St",
"ZipCode": "example_string",
"City": "New York",
"State": "example_string",
"InvoicingAddressCountryID": 123,
"InvoicingAddress": "123 Main St",
"InvoicingAddress2": "123 Main St",
"InvoicingAddress3": "123 Main St",
"InvoicingAddressZipCode": "123 Main St",
"InvoicingAddressCity": "123 Main St",
"InvoicingAddressState": "123 Main St"
})
});
const data = await response.json();
console.log(data);
package main
import (
"fmt"
"net/http"
"bytes"
"encoding/json"
)
func main() {
data := []byte(`{
"CustomerID": 123,
"Name": "John Doe",
"CustomerNo": "example_string",
"NickName": "John Doe",
"OrganizationNo": "example_string",
"Phone": "+1-555-0123",
"Fax": "example_string",
"Email": "user@example.com",
"Website": "example_string",
"VatNo": "example_string",
"CreditorID": "example_string",
"InvoicingName": "John Doe",
"CurrencyID": 123,
"CustomerStatusID": 123,
"CustomerSince": "2024-12-25T10:00:00Z",
"PrimaryKAMID": 123,
"SecondaryKAMID": 123,
"IndustryID": 123,
"UseInvoicingAddress": true,
"CountryID": 123,
"Address": "123 Main St",
"Address2": "123 Main St",
"Address3": "123 Main St",
"ZipCode": "example_string",
"City": "New York",
"State": "example_string",
"InvoicingAddressCountryID": 123,
"InvoicingAddress": "123 Main St",
"InvoicingAddress2": "123 Main St",
"InvoicingAddress3": "123 Main St",
"InvoicingAddressZipCode": "123 Main St",
"InvoicingAddressCity": "123 Main St",
"InvoicingAddressState": "123 Main St"
}`)
req, err := http.NewRequest("PUT", "https://app3.timelog.com/your-account/api/v1/customer/update", bytes.NewBuffer(data))
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/customer/update')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Put.new(uri)
request['Content-Type'] = 'application/json'
request['Authorization'] = 'Bearer YOUR_API_TOKEN'
request.body = '{
"CustomerID": 123,
"Name": "John Doe",
"CustomerNo": "example_string",
"NickName": "John Doe",
"OrganizationNo": "example_string",
"Phone": "+1-555-0123",
"Fax": "example_string",
"Email": "user@example.com",
"Website": "example_string",
"VatNo": "example_string",
"CreditorID": "example_string",
"InvoicingName": "John Doe",
"CurrencyID": 123,
"CustomerStatusID": 123,
"CustomerSince": "2024-12-25T10:00:00Z",
"PrimaryKAMID": 123,
"SecondaryKAMID": 123,
"IndustryID": 123,
"UseInvoicingAddress": true,
"CountryID": 123,
"Address": "123 Main St",
"Address2": "123 Main St",
"Address3": "123 Main St",
"ZipCode": "example_string",
"City": "New York",
"State": "example_string",
"InvoicingAddressCountryID": 123,
"InvoicingAddress": "123 Main St",
"InvoicingAddress2": "123 Main St",
"InvoicingAddress3": "123 Main St",
"InvoicingAddressZipCode": "123 Main St",
"InvoicingAddressCity": "123 Main St",
"InvoicingAddressState": "123 Main St"
}'
response = http.request(request)
puts response.body
{
"Properties": {
"CustomerID": 123,
"ID": "123e4567-e89b-12d3-a456-426614174000",
"Name": "John Doe",
"No": "example_string",
"DefaultMileageDistance": 25,
"CustomerStatusID": 123,
"VATNo": "example_string",
"OrganizationNo": "example_string"
},
"Links": [
{
"Href": "example_string",
"Rel": "example_string"
}
],
"Actions": [
{}
]
}
{
"error": "Unauthorized",
"message": "Authentication required. Please provide a valid API token",
"code": 401
}
{
"error": "Forbidden",
"message": "You don't have permission to access this resource",
"code": 403
}
{
"Code": 100,
"Details": [],
"Message": "Unknown error occur in system, please contact system administrator.",
"Parameters": "customer: {"CustomerID":0,"Name":null, ...}",
"Url": "https://app{server-number}.timelog.com/{account}/api/v1/customer/update"
}
/v1/customer/update
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.The media type of the request body
The customer to change. Identifier of this object, unique per TimeLog site. - Omitted, 0 or not an existing customer — HTTP 500, Code 100 (generic) — not 404.
Company name. - Omitted or null — Stored name cleared.
Alternate key, unique per TimeLog site. - Omitted or null — Stored number cleared. - Feature UniqueCustomerNumber on and number used by another customer — 30169 as HTTP 403 Privilege exception.
- Omitted or null — Cleared.
- Omitted or null — Cleared.
- Omitted or null — Cleared.
- Omitted or null — Cleared.
- Omitted or null — Cleared.
- Omitted or null — Cleared.
- Omitted or null — Cleared.
- Omitted or null — Cleared.
- Omitted or null — Cleared.
Refers to CurrencyRead.CurrencyID. Look up valid values with GET /v1/currency/{status}.
Refers to CustomerStatusRead.CustomerStatusID. Look up valid values with GET /v1/customerstatus.
- ID does not exist — 30018 (HTTP 500, Code 102).
- The rest of the update follows.
- Customer is the account's own company and the status is not a customer status — 31115.
Valid values come from GET /v1/customerstatus.
Time zone: not yet documented. > Not yet documented: constraints → timezone.
Primary owner, as a USER ID.
Refers to UserRead.UserID.
- User does not exist / inactive — 37040 / 37931 (HTTP 500, Code 102).
Secondary owner, as a USER ID.
Refers to UserRead.UserID.
Refers to IndustryRead.IndustryID. Look up valid values with GET /v1/industry/get-all.
- ID does not exist — 30019 (HTTP 500, Code 102).
Valid values come from GET /v1/industry/get-all.
Refers to CountryRead.CountryID. Look up valid values with GET /v1/country/get-all.
Refers to CountryRead.CountryID. Look up valid values with GET /v1/country/get-all.
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.
Body
The customer to change.
Identifier of this object, unique per TimeLog site.
- Omitted, 0 or not an existing customer — HTTP 500, Code 100 (generic) — not 404.
Company name.
- Omitted or null — Stored name cleared.
Alternate key, unique per TimeLog site.
-
Omitted or null — Stored number cleared.
-
Feature UniqueCustomerNumber on and number used by another customer — 30169 as HTTP 403 Privilege exception.
- Omitted or null — Cleared.
- Omitted or null — Cleared.
- Omitted or null — Cleared.
- Omitted or null — Cleared.
- Omitted or null — Cleared.
- Omitted or null — Cleared.
- Omitted or null — Cleared.
- Omitted or null — Cleared.
- Omitted or null — Cleared.
Refers to CurrencyRead.CurrencyID. Look up valid values with GET /v1/currency/{status}.
Refers to CustomerStatusRead.CustomerStatusID. Look up valid values with GET /v1/customerstatus.
-
ID does not exist — 30018 (HTTP 500, Code 102).
-
The rest of the update follows.
-
Customer is the account's own company and the status is not a customer status — 31115.
Valid values come from GET /v1/customerstatus.
Time zone: not yet documented.
Not yet documented: constraints → timezone.
Primary owner, as a USER ID.
Refers to UserRead.UserID.
- User does not exist / inactive — 37040 / 37931 (HTTP 500, Code 102).
Secondary owner, as a USER ID.
Refers to UserRead.UserID.
Refers to IndustryRead.IndustryID. Look up valid values with GET /v1/industry/get-all.
- ID does not exist — 30019 (HTTP 500, Code 102).
Valid values come from GET /v1/industry/get-all.
Refers to CountryRead.CountryID. Look up valid values with GET /v1/country/get-all.
Refers to CountryRead.CountryID. Look up valid values with GET /v1/country/get-all.
Responses
A customer as the REST v1 API returns it: the identifiers, name, number, status and tax numbers only.