Create a time entry
Creates a time entry. The client must supply a ULID as id; if an entry with that id already exists,
the server returns the existing entry with a 200 response. The billing rate is snapshotted at create time.
curl --request POST \
--url https://api.superthread.com/v1/{team_id}/time/entries \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"id": "01HQK6Z9YJZ4M9JX8FVB6QXYAB",
"started_at": 1608742037016,
"duration_seconds": 1800,
"card_id": "2700",
"scope_type": "card",
"scope_id": "<string>",
"time_category_id": "tc_01HQK6Z9YJZ4M9JX8FVB6QXYAB",
"category_id": "<string>",
"description": "Pairing with Alex on the API spec",
"billable": true,
"source": "manual"
}
'import requests
url = "https://api.superthread.com/v1/{team_id}/time/entries"
payload = {
"id": "01HQK6Z9YJZ4M9JX8FVB6QXYAB",
"started_at": 1608742037016,
"duration_seconds": 1800,
"card_id": "2700",
"scope_type": "card",
"scope_id": "<string>",
"time_category_id": "tc_01HQK6Z9YJZ4M9JX8FVB6QXYAB",
"category_id": "<string>",
"description": "Pairing with Alex on the API spec",
"billable": True,
"source": "manual"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
id: '01HQK6Z9YJZ4M9JX8FVB6QXYAB',
started_at: 1608742037016,
duration_seconds: 1800,
card_id: '2700',
scope_type: 'card',
scope_id: '<string>',
time_category_id: 'tc_01HQK6Z9YJZ4M9JX8FVB6QXYAB',
category_id: '<string>',
description: 'Pairing with Alex on the API spec',
billable: true,
source: 'manual'
})
};
fetch('https://api.superthread.com/v1/{team_id}/time/entries', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.superthread.com/v1/{team_id}/time/entries",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'id' => '01HQK6Z9YJZ4M9JX8FVB6QXYAB',
'started_at' => 1608742037016,
'duration_seconds' => 1800,
'card_id' => '2700',
'scope_type' => 'card',
'scope_id' => '<string>',
'time_category_id' => 'tc_01HQK6Z9YJZ4M9JX8FVB6QXYAB',
'category_id' => '<string>',
'description' => 'Pairing with Alex on the API spec',
'billable' => true,
'source' => 'manual'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.superthread.com/v1/{team_id}/time/entries"
payload := strings.NewReader("{\n \"id\": \"01HQK6Z9YJZ4M9JX8FVB6QXYAB\",\n \"started_at\": 1608742037016,\n \"duration_seconds\": 1800,\n \"card_id\": \"2700\",\n \"scope_type\": \"card\",\n \"scope_id\": \"<string>\",\n \"time_category_id\": \"tc_01HQK6Z9YJZ4M9JX8FVB6QXYAB\",\n \"category_id\": \"<string>\",\n \"description\": \"Pairing with Alex on the API spec\",\n \"billable\": true,\n \"source\": \"manual\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.superthread.com/v1/{team_id}/time/entries")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"id\": \"01HQK6Z9YJZ4M9JX8FVB6QXYAB\",\n \"started_at\": 1608742037016,\n \"duration_seconds\": 1800,\n \"card_id\": \"2700\",\n \"scope_type\": \"card\",\n \"scope_id\": \"<string>\",\n \"time_category_id\": \"tc_01HQK6Z9YJZ4M9JX8FVB6QXYAB\",\n \"category_id\": \"<string>\",\n \"description\": \"Pairing with Alex on the API spec\",\n \"billable\": true,\n \"source\": \"manual\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.superthread.com/v1/{team_id}/time/entries")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"id\": \"01HQK6Z9YJZ4M9JX8FVB6QXYAB\",\n \"started_at\": 1608742037016,\n \"duration_seconds\": 1800,\n \"card_id\": \"2700\",\n \"scope_type\": \"card\",\n \"scope_id\": \"<string>\",\n \"time_category_id\": \"tc_01HQK6Z9YJZ4M9JX8FVB6QXYAB\",\n \"category_id\": \"<string>\",\n \"description\": \"Pairing with Alex on the API spec\",\n \"billable\": true,\n \"source\": \"manual\"\n}"
response = http.request(request)
puts response.read_body{
"time_entry": {
"id": "01HQK6Z9YJZ4M9JX8FVB6QXYAB",
"team_id": "tDsu0j19",
"card_id": "2700",
"user_id": "uR2dws11",
"started_at": 1608742037016,
"duration_seconds": 1800,
"billable": true,
"rate_snapshot_cents": 12500,
"currency_snapshot": "GBP",
"source": "manual",
"version": 1,
"type": "time_entry",
"scope_type": "card",
"scope_id": "<string>",
"card_title_snapshot": "Prepare September campaign",
"space_id_snapshot": "space_01HQK6Z9YJZ4M9JX8FVB6QXYAB",
"project_id_snapshot": "2701",
"board_id_snapshot": "board_01HQK6Z9YJZ4M9JX8FVB6QXYAB",
"sprint_id_snapshot": "sprint_01HQK6Z9YJZ4M9JX8FVB6QXYAB",
"ancestor_card_ids_snapshot": [
"<string>"
],
"time_category_id": "tc_01HQK6Z9YJZ4M9JX8FVB6QXYAB",
"category_id": "<string>",
"description": "Pairing with Alex on the API spec",
"needs_review": true,
"review_reason": "abandoned_timer",
"reviewed_at": 1608742037016,
"reviewed_by": "<string>",
"deleted_at": 1608742037016,
"locked_at": 1608742037016,
"time_created": 1608742037016,
"time_updated": 1608742037016
}
}{
"time_entry": {
"id": "01HQK6Z9YJZ4M9JX8FVB6QXYAB",
"team_id": "tDsu0j19",
"card_id": "2700",
"user_id": "uR2dws11",
"started_at": 1608742037016,
"duration_seconds": 1800,
"billable": true,
"rate_snapshot_cents": 12500,
"currency_snapshot": "GBP",
"source": "manual",
"version": 1,
"type": "time_entry",
"scope_type": "card",
"scope_id": "<string>",
"card_title_snapshot": "Prepare September campaign",
"space_id_snapshot": "space_01HQK6Z9YJZ4M9JX8FVB6QXYAB",
"project_id_snapshot": "2701",
"board_id_snapshot": "board_01HQK6Z9YJZ4M9JX8FVB6QXYAB",
"sprint_id_snapshot": "sprint_01HQK6Z9YJZ4M9JX8FVB6QXYAB",
"ancestor_card_ids_snapshot": [
"<string>"
],
"time_category_id": "tc_01HQK6Z9YJZ4M9JX8FVB6QXYAB",
"category_id": "<string>",
"description": "Pairing with Alex on the API spec",
"needs_review": true,
"review_reason": "abandoned_timer",
"reviewed_at": 1608742037016,
"reviewed_by": "<string>",
"deleted_at": 1608742037016,
"locked_at": 1608742037016,
"time_created": 1608742037016,
"time_updated": 1608742037016
}
}{
"error": {
"id": "err5f744ab",
"code": 403,
"sec": "SEC:000-00014",
"message": "You do not have access to this resource",
"date": 1608742037016
}
}Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Headers
Client-generated ULID used to replay a time mutation safely. Optional only for legacy clients during rolling migration.
Path Parameters
Team ID is an alphanumerical string that identifies a Team. This is externally referred to as a "Workspace".
Body
Time entry to create.
Client-supplied ULID. Repeating the same id makes the call idempotent.
"01HQK6Z9YJZ4M9JX8FVB6QXYAB"
unix timestamp in seconds
1608742037016
x >= 11800
Card receiving the entry. Preferred over the legacy scope fields.
"2700"
Legacy time-entry target type retained for rolling-client compatibility.
card, category "card"
Legacy card ID, used when card_id is omitted.
"tc_01HQK6Z9YJZ4M9JX8FVB6QXYAB"
Legacy alias for time_category_id.
"Pairing with Alex on the API spec"
Defaults to the category default (or workspace default) when omitted.
How the time entry was created.
manual, timer, idle "manual"
Response
Existing time entry returned (idempotent replay)
A durable work record. Card ownership metadata is captured when the entry is created, so later card moves or renames do not retroactively change historical reports.
Show child attributes
Show child attributes
curl --request POST \
--url https://api.superthread.com/v1/{team_id}/time/entries \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"id": "01HQK6Z9YJZ4M9JX8FVB6QXYAB",
"started_at": 1608742037016,
"duration_seconds": 1800,
"card_id": "2700",
"scope_type": "card",
"scope_id": "<string>",
"time_category_id": "tc_01HQK6Z9YJZ4M9JX8FVB6QXYAB",
"category_id": "<string>",
"description": "Pairing with Alex on the API spec",
"billable": true,
"source": "manual"
}
'import requests
url = "https://api.superthread.com/v1/{team_id}/time/entries"
payload = {
"id": "01HQK6Z9YJZ4M9JX8FVB6QXYAB",
"started_at": 1608742037016,
"duration_seconds": 1800,
"card_id": "2700",
"scope_type": "card",
"scope_id": "<string>",
"time_category_id": "tc_01HQK6Z9YJZ4M9JX8FVB6QXYAB",
"category_id": "<string>",
"description": "Pairing with Alex on the API spec",
"billable": True,
"source": "manual"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
id: '01HQK6Z9YJZ4M9JX8FVB6QXYAB',
started_at: 1608742037016,
duration_seconds: 1800,
card_id: '2700',
scope_type: 'card',
scope_id: '<string>',
time_category_id: 'tc_01HQK6Z9YJZ4M9JX8FVB6QXYAB',
category_id: '<string>',
description: 'Pairing with Alex on the API spec',
billable: true,
source: 'manual'
})
};
fetch('https://api.superthread.com/v1/{team_id}/time/entries', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.superthread.com/v1/{team_id}/time/entries",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'id' => '01HQK6Z9YJZ4M9JX8FVB6QXYAB',
'started_at' => 1608742037016,
'duration_seconds' => 1800,
'card_id' => '2700',
'scope_type' => 'card',
'scope_id' => '<string>',
'time_category_id' => 'tc_01HQK6Z9YJZ4M9JX8FVB6QXYAB',
'category_id' => '<string>',
'description' => 'Pairing with Alex on the API spec',
'billable' => true,
'source' => 'manual'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.superthread.com/v1/{team_id}/time/entries"
payload := strings.NewReader("{\n \"id\": \"01HQK6Z9YJZ4M9JX8FVB6QXYAB\",\n \"started_at\": 1608742037016,\n \"duration_seconds\": 1800,\n \"card_id\": \"2700\",\n \"scope_type\": \"card\",\n \"scope_id\": \"<string>\",\n \"time_category_id\": \"tc_01HQK6Z9YJZ4M9JX8FVB6QXYAB\",\n \"category_id\": \"<string>\",\n \"description\": \"Pairing with Alex on the API spec\",\n \"billable\": true,\n \"source\": \"manual\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.superthread.com/v1/{team_id}/time/entries")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"id\": \"01HQK6Z9YJZ4M9JX8FVB6QXYAB\",\n \"started_at\": 1608742037016,\n \"duration_seconds\": 1800,\n \"card_id\": \"2700\",\n \"scope_type\": \"card\",\n \"scope_id\": \"<string>\",\n \"time_category_id\": \"tc_01HQK6Z9YJZ4M9JX8FVB6QXYAB\",\n \"category_id\": \"<string>\",\n \"description\": \"Pairing with Alex on the API spec\",\n \"billable\": true,\n \"source\": \"manual\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.superthread.com/v1/{team_id}/time/entries")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"id\": \"01HQK6Z9YJZ4M9JX8FVB6QXYAB\",\n \"started_at\": 1608742037016,\n \"duration_seconds\": 1800,\n \"card_id\": \"2700\",\n \"scope_type\": \"card\",\n \"scope_id\": \"<string>\",\n \"time_category_id\": \"tc_01HQK6Z9YJZ4M9JX8FVB6QXYAB\",\n \"category_id\": \"<string>\",\n \"description\": \"Pairing with Alex on the API spec\",\n \"billable\": true,\n \"source\": \"manual\"\n}"
response = http.request(request)
puts response.read_body{
"time_entry": {
"id": "01HQK6Z9YJZ4M9JX8FVB6QXYAB",
"team_id": "tDsu0j19",
"card_id": "2700",
"user_id": "uR2dws11",
"started_at": 1608742037016,
"duration_seconds": 1800,
"billable": true,
"rate_snapshot_cents": 12500,
"currency_snapshot": "GBP",
"source": "manual",
"version": 1,
"type": "time_entry",
"scope_type": "card",
"scope_id": "<string>",
"card_title_snapshot": "Prepare September campaign",
"space_id_snapshot": "space_01HQK6Z9YJZ4M9JX8FVB6QXYAB",
"project_id_snapshot": "2701",
"board_id_snapshot": "board_01HQK6Z9YJZ4M9JX8FVB6QXYAB",
"sprint_id_snapshot": "sprint_01HQK6Z9YJZ4M9JX8FVB6QXYAB",
"ancestor_card_ids_snapshot": [
"<string>"
],
"time_category_id": "tc_01HQK6Z9YJZ4M9JX8FVB6QXYAB",
"category_id": "<string>",
"description": "Pairing with Alex on the API spec",
"needs_review": true,
"review_reason": "abandoned_timer",
"reviewed_at": 1608742037016,
"reviewed_by": "<string>",
"deleted_at": 1608742037016,
"locked_at": 1608742037016,
"time_created": 1608742037016,
"time_updated": 1608742037016
}
}{
"time_entry": {
"id": "01HQK6Z9YJZ4M9JX8FVB6QXYAB",
"team_id": "tDsu0j19",
"card_id": "2700",
"user_id": "uR2dws11",
"started_at": 1608742037016,
"duration_seconds": 1800,
"billable": true,
"rate_snapshot_cents": 12500,
"currency_snapshot": "GBP",
"source": "manual",
"version": 1,
"type": "time_entry",
"scope_type": "card",
"scope_id": "<string>",
"card_title_snapshot": "Prepare September campaign",
"space_id_snapshot": "space_01HQK6Z9YJZ4M9JX8FVB6QXYAB",
"project_id_snapshot": "2701",
"board_id_snapshot": "board_01HQK6Z9YJZ4M9JX8FVB6QXYAB",
"sprint_id_snapshot": "sprint_01HQK6Z9YJZ4M9JX8FVB6QXYAB",
"ancestor_card_ids_snapshot": [
"<string>"
],
"time_category_id": "tc_01HQK6Z9YJZ4M9JX8FVB6QXYAB",
"category_id": "<string>",
"description": "Pairing with Alex on the API spec",
"needs_review": true,
"review_reason": "abandoned_timer",
"reviewed_at": 1608742037016,
"reviewed_by": "<string>",
"deleted_at": 1608742037016,
"locked_at": 1608742037016,
"time_created": 1608742037016,
"time_updated": 1608742037016
}
}{
"error": {
"id": "err5f744ab",
"code": 403,
"sec": "SEC:000-00014",
"message": "You do not have access to this resource",
"date": 1608742037016
}
}