Give an employee a competence
Adds one competence with a value (rating) to one employee.
Creates the employee-competence row (employee, competence, value). The caller needs the Employee skills create/edit privilege covering that employee. The response is the literal null — the new employee-competence ID is NOT returned; read it back with GET /v2/employee-competences?userId=. For several competences at once, prefer the batch create, which skips existing pairs instead of failing.
Use it to:
- Record a newly acquired skill for an employee
Not for:
- Changing the value of a competence the employee already has —
PUT /v2/employee-competences - Several competences in one call —
POST /v2/employee-competences/bulk
Rules across fields:
- R1: The (UserId, CompetenceId) pair must not exist yet.
Behaviour:
- Not idempotent.
- Safe to retry only under a condition. A retry after a lost success fails with 500 Code 100 (unique constraint) — check with GET before retrying.
- Changes are visible to the next read immediately.
Call first: GET /v1/user, GET /v2/employee-competences/available
Next: GET /v2/employee-competences
See also: POST /v2/employee-competences/bulk
Not yet documented: errors; examples.
curl -X POST "https://app3.timelog.com/your-account/api/v2/employee-competences" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-d '{
"UserId": 123,
"CompetenceId": 123,
"Value": 42
}'
import requests
import json
url = "https://app3.timelog.com/your-account/api/v2/employee-competences"
headers = {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_API_TOKEN"
}
data = {
"UserId": 123,
"CompetenceId": 123,
"Value": 42
}
response = requests.post(url, headers=headers, json=data)
print(response.json())
const response = await fetch("https://app3.timelog.com/your-account/api/v2/employee-competences", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_API_TOKEN"
},
body: JSON.stringify({
"UserId": 123,
"CompetenceId": 123,
"Value": 42
})
});
const data = await response.json();
console.log(data);
package main
import (
"fmt"
"net/http"
"bytes"
"encoding/json"
)
func main() {
data := []byte(`{
"UserId": 123,
"CompetenceId": 123,
"Value": 42
}`)
req, err := http.NewRequest("POST", "https://app3.timelog.com/your-account/api/v2/employee-competences", 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/v2/employee-competences')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri)
request['Content-Type'] = 'application/json'
request['Authorization'] = 'Bearer YOUR_API_TOKEN'
request.body = '{
"UserId": 123,
"CompetenceId": 123,
"Value": 42
}'
response = http.request(request)
puts response.body
"null"
{
"error": "Unauthorized",
"message": "Authentication required. Please provide a valid API token",
"code": 401
}
{
"Code": 102,
"Details": [
{
"Message": "No user with UserID: 0 exist",
"ErrorCode": 37040
}
],
"Message": "Business rules exception.",
"Parameters": "model: {"UserId":0,"CompetenceId":0,"Value":0}",
"Url": "https://app{server-number}.timelog.com/{account}/api/v2/employee-competences"
}
/v2/employee-competences
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
UserID of the employee who gets the competence.
Can be set on create only.
Refers to UserRead.UserID. Look up valid values with GET /v1/user.
- Missing, 0 or not an existing user — 500 Code 102 / 37040 (captured for a missing value).
- User deactivated — 500 Code 102 / 37931.
- Caller has no Employee skills privilege covering this employee — 500 Code 102 / 38015.
ID of the competence to give (GET /v2/employee-competences/available lists the ones the employee does not have yet).
Can be set on create only.
Refers to CompetenceRead.Id. Look up valid values with GET /v2/employee-competences/available.
- Not checked earlier.
- The employee already has this competence — Unique constraint (UserID, CompetenceID) → 500 Code 100. Use PUT to change the value.
- Competence is inactive — Not checked: an inactive competence can be given (the 'available' list hides inactive ones).
> Not yet documented: behaviour.
The employee's value (rating) for the competence. Stored as given; the scale is not defined in the API (see EmployeeCompetenceItemRead.Value). Can be set on create only. Contains personal data. - Omitted — Binds as 0 and is stored as 0. - No range rule in the API. > Not yet documented: behaviour.
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
UserID of the employee who gets the competence.
Can be set on create only.
Refers to UserRead.UserID. Look up valid values with GET /v1/user.
-
Missing, 0 or not an existing user — 500 Code 102 / 37040 (captured for a missing value).
-
User deactivated — 500 Code 102 / 37931.
-
Caller has no Employee skills privilege covering this employee — 500 Code 102 / 38015.
ID of the competence to give (GET /v2/employee-competences/available lists the ones the employee does not have yet).
Can be set on create only.
Refers to CompetenceRead.Id. Look up valid values with GET /v2/employee-competences/available.
-
Not checked earlier.
-
The employee already has this competence — Unique constraint (UserID, CompetenceID) → 500 Code 100. Use PUT to change the value.
-
Competence is inactive — Not checked: an inactive competence can be given (the 'available' list hides inactive ones).
Not yet documented: behaviour.
The employee's value (rating) for the competence. Stored as given; the scale is not defined in the API (see EmployeeCompetenceItemRead.Value).
Can be set on create only.
Contains personal data.
-
Omitted — Binds as 0 and is stored as 0.
-
No range rule in the API.
Not yet documented: behaviour.
Responses
*Success without content: HTTP 200 with the literal JSON body null. Literal JSON null (TafSuccessResult).
Order: none
Empty result: none*