NAV
cURL C# VB.NET Java AJAX NodeJS PHP Ruby Python Perl Go Swift

Introduction

TSheets is now QuickBooks Time

The TSheets API provides access to the same rich features as our top-rated web-based and mobile apps. With it you can quickly build time-tracking solutions that simplify workflows and save customers time and money. For inspiration, have a look at the amazing integrations our partners have built on our App Marketplace.

Based on REST principles, it's very easy to write and test applications. You can use your browser to access URLs, and practically any TLS-capable HTTP client in any programming language to interact with the API. The API allows you to query metadata about your account, users, jobcodes, timesheets, GPS points, and custom fields. You can also create timesheets, users, jobcodes, etc. All access to the API occurs over a TLS-encrypted secure channel, so your API client must support TLS. To ensure data privacy, unencrypted HTTP is not supported.

Getting Started

getting_started-1getting_started-1getting_started-1

1) Signup for a Free Trial
Visit our site today and get started within minutes

2) Obtain an Access Token
See the guided walkthrough to complete the simple steps. (See also Authentication)

3) Build your Integration
For the quickest start, try our Postman Collection along with the API Reference documentation.

Postman Collection

The quickest way to get started is to use our Postman request collection. The following steps will help you get up and running. If you prefer, our API can also easily be explored with other tools, like cURL.

1) Open the TSheets Postman Collection

2) Configure the Postman Environment

3) Explore the API

Base URL

All URLs referenced in the documentation have the following base:

https://rest.tsheets.com/api/v1

Contribute


Found an error, or would otherwise like to contribute to our API documentation? Submit a pull request to our public GitHub repository.

Request Throttling

To prevent abuse of the TSheets API, we limit requests to a maximum of 300 calls within any 5 minute time window (subject to change). Rate limiting is primarily considered on a per-connection basis (per access token). If you exceed the current rate limit, you will receive a 429 'Too many requests' response from our API. You will continue to receive a 429 response until you're out of the current time window. The threshold and time window may adjust dynamically downward if you are found to be abusing the system.

Response Size Limit

Each request response will return a maximum of 200 results per page (regardless of whether the limit parameter is sent with your request). To receive the full response, look for the "more": true attribute and iterate sending a new request with the page parameter incremented until you receive "more": false in the response payload.

SDK's & Helper Libraries

ms.net-logophp

This documentation explains the format for calls to the TSheets API with code snippets in cURL and several other languages. Full SDK's and helper libraries are also available upon request to make it even easier for you to get started with TSheets.

Full SDK's

Helper Libraries

While a helper library can make it easier to consume the API, it is certainly not necessary and the API is still very straight-forward to use even without one. Simply use a built-in http class or library for your language of choice.

Connection Count Information

By default we allow you to connect to 3 additional client accounts (besides your own) via your API application keys. If you are building an integration and are interested in enabling your application for use by any TSheets customer, please contact us.

Here are a few of the things we'll be looking for before allowing your application access to our other TSheets customers:

Getting Help

If you have any questions using our API, please visit Intuit Developer Site or QuickBooks Community Page.

Authentication

OAuth2.0

TSheets uses OAuth2 for authentication and authorization of our API. OAuth2 is a protocol designed to let third-party applications authenticate to perform actions as a user, without getting the user's password. There are several libraries available that implement the protocol, and a good list can be found at the OAuth2 home page. Through the use of OAuth2, you'll go through the process of obtaining a token and then you'll use that token in every request made to the API to verify your identity.

Obtaining a Token

Before you can make any request of the API, you must first authenticate. Once you've authenticated, you will be given an access token that may be used for all subsequent requests.

Performing the OAuth2 token request flow requires an OAuth client ID and an OAuth client secret. To obtain these application credentials, you will need to install the API Add-On in your TSheets account and follow the instructions found there. The OAuth client secret should never be shared.

There are 2 steps required in order to obtain an access token, as follows:

Step 1. Authorization Request

This first step consists of a user authorizing your application to access their information on TSheets. To do this, you'll create a link somewhere on your site that they can use to initiate the process. The link will contain several parameters that are necessary for TSheets to consider it valid. The user should use a web browser to follow the link and perform the authorization request.

Once the user is directed to access the authorization endpoint at TSheets ('authorization server' in OAuth2-speak), two things will happen:

The link that a user will follow to perform an authorization request is made to the /authorize end-point:

Example: Authorization Request.

Request

curl "https://rest.tsheets.com/api/v1/authorize?response_type=code&client_id=MYAPPCLIENTID&redirect_uri=https://somedomain.com/callback&state=MYSTATE" \
var client = new RestClient("https://rest.tsheets.com/api/v1/authorize?response_type=code&client_id=MYAPPCLIENTID&redirect_uri=https://somedomain.com/callback&state=MYSTATE");
var request = new RestRequest(Method.GET);
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/authorize?response_type=code&client_id=MYAPPCLIENTID&redirect_uri=https://somedomain.com/callback&state=MYSTATE")
Dim request = New RestRequest(Method.[GET])
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/authorize?response_type=code&client_id=MYAPPCLIENTID&redirect_uri=https://somedomain.com/callback&state=MYSTATE")
  .get()
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/authorize?response_type=code&client_id=MYAPPCLIENTID&redirect_uri=https://somedomain.com/callback&state=MYSTATE",
  "method": "GET",
  "headers": {
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'GET',
  url: 'https://rest.tsheets.com/api/v1/authorize',
  qs: {
    response_type: 'code',
    client_id: 'MYAPPCLIENTID',
    redirect_uri: 'https://somedomain.com/callback',
    state: 'MYSTATE',
  },
  headers: 
   {
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/authorize');
$request->setMethod(HTTP_METH_GET);

$request->setQueryData(array(
  'response_type' => 'code',
  'client_id' => 'MYAPPCLIENTID',
  'redirect_uri' => 'https://somedomain.com/callback',
  'state' => 'MYSTATE',
));

$request->setHeaders(array(
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/authorize?response_type=code&client_id=MYAPPCLIENTID&redirect_uri=https://somedomain.com/callback&state=MYSTATE")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Get.new(url)

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/authorize"

querystring = {
  "response_type":"code",
  "client_id":"MYAPPCLIENTID",
  "redirect_uri":"https://somedomain.com/callback",
  "state":"MYSTATE",
}

payload = ""
headers = {
  }

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/authorize?response_type=code&client_id=MYAPPCLIENTID&redirect_uri=https://somedomain.com/callback&state=MYSTATE"

  req, _ := http.NewRequest("GET", url, nil)


  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/authorize?response_type=code&client_id=MYAPPCLIENTID&redirect_uri=https://somedomain.com/callback&state=MYSTATE")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest, completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();


$url="https://rest.tsheets.com/api/v1/authorize?response_type=code&client_id=MYAPPCLIENTID&redirect_uri=https://somedomain.com/callback&state=MYSTATE"; 

$client->GET($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

HTTP Request

gethttps://rest.tsheets.com/api/v1/authorize

Parameters

response_type
required
String This parameter MUST always be set to the string 'code'.
client_id
required
String This parameter MUST always be set to the value of the OAuth client ID that you obtained when you registered your app in the TSheets API Add-On in your TSheets account.
redirect_uri
required
String The HTTPS url that you submitted as the 'OAuth Redirect URI' when you set up your app in the TSheets API Add-On. If the user grants access to your application, we'll redirect them back to this url with a temporary code in a code parameter. They'll use this code to obtain an access token.
state
required
String A random value used by the client to maintain state between the request and callback. The authorization server includes this value when redirecting the user-agent back to the client. It is used to protect against cross-site request forgery attacks. If the states don't match, the request has been created by a third party and the process should be aborted.
display_mode
optional
String Optional. Can be 'create' or 'login'. Default is 'login'. If 'login', the form for logging into an existing TSheets account is displayed first. If 'create', the form for creating a new TSheets account is shown first.

Upon successful authorization and if the user grants access for their data to the app, TSheets will redirect the connected user to the redirect_uri (https://somedomain.com/callback in this example) found in the original request, and two parameters will be appended to it:

1) code - the unique code generated for this request - to be used in the token call later in the flow.
2) state - the value passed in 'state' in the original authorization request.

For example:

https://somedomain.com/callback?code=bbcaef03191517dfb60d0305bfea38ea995af1az&state=MYSTATE

The server that handles the request to https://somedomain.com/callback should extract and save the code parameter value, as it is required as part of the next step in the flow. The state value should be compared to what was originally sent and verified to be the same.

If the call to the /authorize end-point is malformed, or if the user denies access to the requesting app, then TSheets will still redirect the user back to the redirect_uri, but instead it will append error and error_description parameters. For example:

https://somedomain.com/callback?error=SOME_ERROR&error_description=SOME_DESCRIPTION

Step 2. Access Token Request

At this point you have an authorization 'code' for the user of your app. To exchange the code for an access token, your application needs to do a POST to our /grant API end-point. In this step, TSheets will check that the authorization code was issued to the same application that is making the token request.

The access_token should be included with every call to the API. Failure to include the access token or using an expired token will result in a 401 response. Note that when you receive your access token, you also receive the user_id and client_id properties that are associated with the user that the access token is for. These properties are provided for convenience, to potentially save you the need for making a request to the current user endpoint.

If the client has IP Authorization security enabled with the block all access option turned on, the request could fail with a 499 status code if it comes from an unauthorized IP address. All subsequent requests will also fail until the device switches to an authorized IP address.

Example: Access Token Request.

Request

curl -X POST \
  https://rest.tsheets.com/api/v1/grant \
  -d 'grant_type=authorization_code&client_id=MYAPPCLIENTID&client_secret=MYAPPSECRET&code=bbcaef03191517dfb60d0305bfea38ea995af1az&redirect_uri=https%3A%2F%2Fsomedomain.com%2Fcallback'
var client = new RestClient("https://rest.tsheets.com/api/v1/grant");
var request = new RestRequest(Method.POST);
request.AddParameter("application/x-www-form-urlencoded", "grant_type=authorization_code&client_id=MYAPPCLIENTID&client_secret=MYAPPSECRET&code=bbcaef03191517dfb60d0305bfea38ea995af1az&redirect_uri=https%3A%2F%2Fsomedomain.com%2Fcallback", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/grant")
Dim request = New RestRequest(Method.POST)
request.AddParameter("application/x-www-form-urlencoded", "grant_type=authorization_code&client_id=MYAPPCLIENTID&client_secret=MYAPPSECRET&code=bbcaef03191517dfb60d0305bfea38ea995af1az&redirect_uri=https%3A%2F%2Fsomedomain.com%2Fcallback", ParameterType.RequestBody);
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
RequestBody body = RequestBody.create(mediaType, "grant_type=authorization_code&client_id=MYAPPCLIENTID&client_secret=MYAPPSECRET&code=bbcaef03191517dfb60d0305bfea38ea995af1az&redirect_uri=https%3A%2F%2Fsomedomain.com%2Fcallback");
Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/grant")
  .post(body)
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/authorize?response_type=code&client_id=MYAPPCLIENTID&redirect_uri=https://somedomain.com/callback&state=MYSTATE",
  "method": "POST",
  "headers": {
  },
  "processData": false,
  "data": {
    "grant_type": "authorization_code",
    "client_id": "MYAPPCLIENTID",
    "client_secret": "MYAPPSECRET",
    "code": "bbcaef03191517dfb60d0305bfea38ea995af1az",
    "redirect_uri": "https%3A%2F%2Fsomedomain.com%2Fcallback"
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'POST',
  url: 'https://rest.tsheets.com/api/v1/grant',
  headers: 
  { 
  },
  form:
   {
      grant_type: 'authorization_code',
      client_id: 'MYAPPCLIENTID',
      client_secret: 'MYAPPSECRET',
      code: 'bbcaef03191517dfb60d0305bfea38ea995af1az',
      redirect_uri: 'https%3A%2F%2Fsomedomain.com%2Fcallback' }
};

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/grant');
$request->setMethod(HTTP_METH_POST);

$request->setHeaders(array(
));

$request->setContentType('application/x-www-form-urlencoded');
$request->setPostFields(array(
  'grant_type' => 'authorization_code',
  'client_id' => 'MYAPPCLIENTID',
  'client_secret' => 'MYAPPSECRET',
  'code' => 'bbcaef03191517dfb60d0305bfea38ea995af1az',
  'redirect_uri' => 'https%3A%2F%2Fsomedomain.com%2Fcallback'
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/grant")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Post.new(url)
request.body = "grant_type=authorization_code&client_id=MYAPPCLIENTID&client_secret=MYAPPSECRET&code=bbcaef03191517dfb60d0305bfea38ea995af1az&redirect_uri=https%3A%2F%2Fsomedomain.com%2Fcallback"

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/grant"

payload = "grant_type=authorization_code&client_id=MYAPPCLIENTID&client_secret=MYAPPSECRET&code=bbcaef03191517dfb60d0305bfea38ea995af1az&redirect_uri=https%3A%2F%2Fsomedomain.com%2Fcallback"
headers = {
    }

response = requests.request("POST", url, data=payload, headers=headers)

print(response.text)
package main

import (
  "fmt"
  "strings"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/grant"

  payload := strings.NewReader("grant_type=authorization_code&client_id=MYAPPCLIENTID&client_secret=MYAPPSECRET&code=bbcaef03191517dfb60d0305bfea38ea995af1az&redirect_uri=https%3A%2F%2Fsomedomain.com%2Fcallback")

  req, _ := http.NewRequest("POST", url, payload)


  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))

}
import Foundation

let headers = [
]

let postData = NSMutableData(data: "grant_type=authorization_code".data(using: STring.Encoding.utf8)!)
postData.append("&client_id=MYAPPCLIENTID".data(using: String.Encoding.utf8)!)  
postData.append("&client_secret=MYAPPSECRET".data(using: String.Encoding.utf8)!)  
postData.append("&code=bbcaef03191517dfb60d0305bfea38ea995af1az".data(using: String.Encoding.utf8)!)  
postData.append("&redirect_uri=https%3A%2F%2Fsomedomain.com%2Fcallback".data(using: String.Encoding.utf8)!)  

let request = NSMutableURLRequest(
  url: NSURL(string: "http://rest.tsheets.com/api/v1/grant")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest,
  completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();


$req = 'grant_type=authorization_code&client_id=MYAPPCLIENTID&client_secret=MYAPPSECRET&code=bbcaef03191517dfb60d0305bfea38ea995af1az&redirect_uri=https%3A%2F%2Fsomedomain.com%2Fcallback';

$url="http://rest.tsheets.com/api/v1/grant"; 

$client->POST($url, $req);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "access_token":"84ec7a2f2b1379990caea347d67e713f34f2d5dz",
  "expires_in":864000,
  "token_type":"bearer",
  "scope":"",
  "refresh_token":"0ed645dbcfaca681e37df26df6f39d273330e7a0",
  "user_id":"12345",
  "company_id":"12345",
  "client_url":"blakemoving"
}

HTTP Request

posthttps://rest.tsheets.com/api/v1/grant

Parameters

grant_type
required
String This parameter MUST always be set to the string 'authorization_code'. This tells us what type of code is included.
client_id
required
String This parameter MUST always be set to the value of the OAuth client ID that you obtained when you set up your app in the API Add-On in your TSheets account.
client_secret
required
String This parameter MUST always be set to the value of the OAuth client secret that you obtained when you set up your app in the API Add-On in your TSheets account.
code
required
String The 'code' being exchanged for an access token. This should be the authorization code received above.
redirect_uri
required
String The HTTPS url that was included in Step 1 of the authorization request. The value must be identical.

Make Requests With the Access Token

Example: Making a request with an access token.

Request

curl "https://rest.tsheets.com/api/v1/users?limit=1" \
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/users?limit=1");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/users?limit=1")
Dim request = New RestRequest(Method.[GET])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/users?limit=1")
  .get()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/users?limit=1",
  "method": "GET",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'GET',
  url: 'https://rest.tsheets.com/api/v1/users',
  qs: {
    limit: '1',
  },
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/users');
$request->setMethod(HTTP_METH_GET);

$request->setQueryData(array(
  'limit' => '1',
));

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/users?limit=1")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/users"

querystring = {
  "limit":"1",
}

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/users?limit=1"

  req, _ := http.NewRequest("GET", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/users?limit=1")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest, completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/users?limit=1"; 

$client->GET($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Once you have an OAuth access token, you can use it to make API requests. Use the HTTP Authorization header when making a request.

Storing a Token

When appropriate, applications should store the token locally, rather than requesting a new token for the same user each time the user uses the application. If the token is deleted or expires, the application will get a 401 Unauthorized error from the API, in which case the application should perform the OAuth flow again to receive a new token. Storing a token is in many ways equivalent to storing the user's password, so tokens should be stored and used in a secure manner.

Refreshing an Access Token

Access tokens expire after expires_in seconds (see example response). In order to avoid sending the user through the OAuth2 process described above every time they want to access resources, API consumers can exchange a refresh_token for a new access_token before the current one expires. To do so, you make a request similar to the original request described above.

Example: Refresh Token Request.

Request

curl -X POST \
  https://rest.tsheets.com/api/v1/grant \
  -H 'Authorization: Bearer <TOKEN>' \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -d 'grant_type=refresh_token&client_id=MYAPPCLIENTID&client_secret=MYAPPSECRET&refresh_token=0ed645dbcfaca681e37df26df6f39d273330e7a0'
var client = new RestClient("https://rest.tsheets.com/api/v1/grant");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <TOKEN>");
request.AddHeader("Content-Type", "application/x-www-form-urlencoded");
request.AddParameter("application/x-www-form-urlencoded", "grant_type=refresh_token&client_id=MYAPPCLIENTID&client_secret=MYAPPSECRET&refresh_token=0ed645dbcfaca681e37df26df6f39d273330e7a0", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/grant")
Dim request = New RestRequest(Method.POST)
request.AddHeader("Authorization", "Bearer <TOKEN>")
request.AddHeader("Content-Type", "application/x-www-form-urlencoded")
request.AddParameter("application/x-www-form-urlencoded", "grant_type=refresh_token&client_id=MYAPPCLIENTID&client_secret=MYAPPSECRET&refresh_token=0ed645dbcfaca681e37df26df6f39d273330e7a0", ParameterType.RequestBody);
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
RequestBody body = RequestBody.create(mediaType, "grant_type=refresh_token&client_id=MYAPPCLIENTID&client_secret=MYAPPSECRET&refresh_token=0ed645dbcfaca681e37df26df6f39d273330e7a0");
Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/grant")
  .post(body)
  .addHeader("Authorization", "Bearer <TOKEN>")
  .addHeader("Content-Type", "application/x-www-form-urlencoded")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/users?limit=1",
  "method": "POST",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
    "Content-Type", "application/x-www-form-urlencoded",
  },
  "processData": false,
  "data": {
    "grant_type": "refresh_token",
    "client_id": "MYAPPCLIENTID",
    "client_secret": "MYAPPSECRET",
    "refresh_token": "0ed645dbcfaca681e37df26df6f39d273330e7a0"
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'POST',
  url: 'https://rest.tsheets.com/api/v1/grant',
  headers: 
  { 
     'Authorization': 'Bearer <TOKEN>',
     'Content-Type': 'application/x-www-form-urlencoded',
  },
  form:
   {
      grant_type: 'refresh_token',
      client_id: 'MYAPPCLIENTID',
      client_secret: 'MYAPPSECRET',
      refresh_token: '0ed645dbcfaca681e37df26df6f39d273330e7a0' }
};

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/grant');
$request->setMethod(HTTP_METH_POST);

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
  'Content-Type' => 'application/x-www-form-urlencoded',
));

$request->setContentType('application/x-www-form-urlencoded');
$request->setPostFields(array(
  'grant_type' => 'refresh_token',
  'client_id' => 'MYAPPCLIENTID',
  'client_secret' => 'MYAPPSECRET',
  'refresh_token' => '0ed645dbcfaca681e37df26df6f39d273330e7a0'
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/grant")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <TOKEN>',
request["Content-Type"] = 'application/x-www-form-urlencoded',
request.body = "grant_type=refresh_token&client_id=MYAPPCLIENTID&client_secret=MYAPPSECRET&refresh_token=0ed645dbcfaca681e37df26df6f39d273330e7a0"

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/grant"

payload = "grant_type=refresh_token&client_id=MYAPPCLIENTID&client_secret=MYAPPSECRET&refresh_token=0ed645dbcfaca681e37df26df6f39d273330e7a0"
headers = {
    'Authorization': 'Bearer <TOKEN>',
    'Content-Type': 'application/x-www-form-urlencoded',
    }

response = requests.request("POST", url, data=payload, headers=headers)

print(response.text)
package main

import (
  "fmt"
  "strings"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/grant"

  payload := strings.NewReader("grant_type=refresh_token&client_id=MYAPPCLIENTID&client_secret=MYAPPSECRET&refresh_token=0ed645dbcfaca681e37df26df6f39d273330e7a0")

  req, _ := http.NewRequest("POST", url, payload)

  req.Header.Add("Authorization", "Bearer <TOKEN>")
  req.Header.Add("Content-Type", "application/x-www-form-urlencoded")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))

}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
   "Content-Type": "application/x-www-form-urlencoded",
]

let postData = NSMutableData(data: "grant_type=refresh_token".data(using: STring.Encoding.utf8)!)
postData.append("&client_id=MYAPPCLIENTID".data(using: String.Encoding.utf8)!)  
postData.append("&client_secret=MYAPPSECRET".data(using: String.Encoding.utf8)!)  
postData.append("&refresh_token=0ed645dbcfaca681e37df26df6f39d273330e7a0".data(using: String.Encoding.utf8)!)  

let request = NSMutableURLRequest(
  url: NSURL(string: "http://rest.tsheets.com/api/v1/grant")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest,
  completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');
$client->addHeader('Content-Type', 'application/x-www-form-urlencoded');

$req = 'grant_type=refresh_token&client_id=MYAPPCLIENTID&client_secret=MYAPPSECRET&refresh_token=0ed645dbcfaca681e37df26df6f39d273330e7a0';

$url="http://rest.tsheets.com/api/v1/grant"; 

$client->POST($url, $req);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "access_token":"c65931f72f0a905bea92fb2dce8e4c25151c02e9",
  "expires_in":864000,
  "token_type":"bearer",
  "scope":"",
  "refresh_token":"9eaec192df27b22e6575e438a4159639937605c7",
  "user_id":"12345",
  "company_id":"12345",
  "client_url":"blakemoving"
}

HTTP Request

posthttps://rest.tsheets.com/api/v1/grant

Parameters

grant_type
required
String This parameter MUST be set to the string 'refresh_token'.
client_id
required
String This parameter MUST always be set to the value of the OAuth client ID that you obtained when you set up your app in the API Add-On in your TSheets account.
client_secret
required
String This parameter MUST always be set to the value of the OAuth client secret that you obtained when you set up your app in the API Add-On in your TSheets account.
refresh_token
required
String This parameter is the refresh_token that you're exchanging for a new access_token.

Request Formats

Retrieve resources with the HTTP GET Method

Example: Retrieving a resource.

Request

curl "https://rest.tsheets.com/api/v1/users?limit=5&usernames=frank,fred" \
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/users?limit=5&usernames=frank,fred");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/users?limit=5&usernames=frank,fred")
Dim request = New RestRequest(Method.[GET])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/users?limit=5&usernames=frank,fred")
  .get()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/users?limit=5&usernames=frank,fred",
  "method": "GET",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'GET',
  url: 'https://rest.tsheets.com/api/v1/users',
  qs: {
    limit: '5',
    usernames: 'frank,fred',
  },
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/users');
$request->setMethod(HTTP_METH_GET);

$request->setQueryData(array(
  'limit' => '5',
  'usernames' => 'frank,fred',
));

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/users?limit=5&usernames=frank,fred")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/users"

querystring = {
  "limit":"5",
  "usernames":"frank,fred",
}

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/users?limit=5&usernames=frank,fred"

  req, _ := http.NewRequest("GET", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/users?limit=5&usernames=frank,fred")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest, completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/users?limit=5&usernames=frank,fred"; 

$client->GET($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

You retrieve a representation of an object by sending an HTTP GET action to the resource's endpoint url. Filters can be specified for the request using a query string following the endpoint url. For example, you could GET a list of users, showing 5 per page and having the username 'frank' or 'fred' with the following:

Create new resources with the HTTP POST Method

Example: Creating a new resource.

Request

curl -X POST \
  https://rest.tsheets.com/api/v1/users \
  -H 'Authorization: Bearer <TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '<REQUEST BODY>'
var client = new RestClient("https://rest.tsheets.com/api/v1/users");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <TOKEN>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "<REQUEST BODY>", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/users")
Dim request = New RestRequest(Method.POST)
request.AddHeader("Authorization", "Bearer <TOKEN>")
request.AddHeader("Content-Type", "application/json")
request.AddParameter("application/json", "<REQUEST BODY>", ParameterType.RequestBody);
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<REQUEST BODY>");
Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/users")
  .post(body)
  .addHeader("Authorization", "Bearer <TOKEN>")
  .addHeader("Content-Type", "application/json")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/users?limit=5&usernames=frank,fred",
  "method": "POST",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
    "Content-Type", "application/json",
  },
  "processData": false,
  "data": "<REQUEST BODY>"
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'POST',
  url: 'https://rest.tsheets.com/api/v1/users',
  headers: 
  { 
     'Authorization': 'Bearer <TOKEN>',
     'Content-Type': 'application/json',
  },
  body: '<REQUEST BODY>',
  json: true };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/users');
$request->setMethod(HTTP_METH_POST);

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
  'Content-Type' => 'application/json',
));

$request->setBody('<REQUEST BODY>');

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/users")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <TOKEN>',
request["Content-Type"] = 'application/json',
request.body = "<REQUEST BODY>"

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/users"

payload = "<REQUEST BODY>"
headers = {
    'Authorization': 'Bearer <TOKEN>',
    'Content-Type': 'application/json',
    }

response = requests.request("POST", url, data=payload, headers=headers)

print(response.text)
package main

import (
  "fmt"
  "strings"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/users"

  payload := strings.NewReader("<REQUEST BODY>")

  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, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))

}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
   "Content-Type": "application/json",
]
let parameters = <REQUEST BODY> as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/users")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest,
  completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');
$client->addHeader('Content-Type', 'application/json');

$req = '<REQUEST BODY>';

$url="https://rest.tsheets.com/api/v1/users"; 

$client->POST($url, $req);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

You can add a new object by sending an HTTP POST action to the resource's endpoint url. You must include a JSON representation of the object in your POST body, and the Content-Type: application/json header must be set in your request.

Update existing resources with the HTTP PUT Method

Example: Updating a resource.

Request

curl -X PUT \
  https://rest.tsheets.com/api/v1/users \
  -H 'Authorization: Bearer <TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '<REQUEST BODY>'
var client = new RestClient("https://rest.tsheets.com/api/v1/users");
var request = new RestRequest(Method.PUT);
request.AddHeader("Authorization", "Bearer <TOKEN>");
request.AddHeader("Content-Type", "application/json");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/users")
Dim request = New RestRequest(Method.PUT)
request.AddHeader("Authorization", "Bearer <TOKEN>")
request.AddHeader("Content-Type", "application/json")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<REQUEST BODY>");
Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/users")
  .put(body)
  .addHeader("Authorization", "Bearer <TOKEN>")
  .addHeader("Content-Type", "application/json")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/users?limit=5&usernames=frank,fred",
  "method": "PUT",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
    "Content-Type", "application/json",
  },
  "processData": false,
  "data": "<REQUEST BODY>"
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'PUT',
  url: 'https://rest.tsheets.com/api/v1/users',
  headers: 
  { 
     'Authorization': 'Bearer <TOKEN>',
     'Content-Type': 'application/json',
  },
  body: '<REQUEST BODY>',
  json: true };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/users');
$request->setMethod(HTTP_METH_PUT);

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
  'Content-Type' => 'application/json',
));

$request->setBody('<REQUEST BODY>');

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/users")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <TOKEN>',
request["Content-Type"] = 'application/json',
request.body = "<REQUEST BODY>"

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/users"

payload = "<REQUEST BODY>"
headers = {
    'Authorization': 'Bearer <TOKEN>',
    'Content-Type': 'application/json',
    }

response = requests.request("PUT", url, data=payload, headers=headers)

print(response.text)
package main

import (
  "fmt"
  "strings"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/users"

  payload := strings.NewReader("<REQUEST BODY>")

  req, _ := http.NewRequest("PUT", 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, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))

}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
   "Content-Type": "application/json",
]
let parameters = <REQUEST BODY> as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(
  url: NSURL(string: "http://rest.tsheets.com/api/v1/users")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "PUT"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest,
  completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');
$client->addHeader('Content-Type', 'application/json');

$req = '<REQUEST BODY>';

$url="http://rest.tsheets.com/api/v1/users"; 

$client->PUT($url, $req);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

You can edit an existing object by sending an HTTP PUT action to the resource's endpoint url. You must include a JSON representation of the object's modified properties in your PUT body, and the Content-Type: application/json header must be set in your request. For example, you could PUT changes using the user's unique id and the properties and values that you would like changed:

Delete resources with the HTTP DELETE Method

Example: Deleting resources.

Request

curl -X DELETE "https://rest.tsheets.com/api/v1/jobcode_assignments?ids=56788,58078"
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/jobcode_assignments?ids=56788,58078");
var request = new RestRequest(Method.DELETE);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/jobcode_assignments?ids=56788,58078")
Dim request = New RestRequest(Method.[DELETE])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/jobcode_assignments?ids=56788,58078")
  .delete()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/jobcode_assignments?ids=56788,58078",
  "method": "DELETE",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'DELETE',
  url: 'https://rest.tsheets.com/api/v1/jobcode_assignments',
  qs: {
    ids: '56788,58078',
  },
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/jobcode_assignments');
$request->setMethod(HTTP_METH_DELETE);

$request->setQueryData(array(
  'ids' => '56788,58078',
));

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/jobcode_assignments?ids=56788,58078")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Delete.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/jobcode_assignments"

querystring = {
  "ids":"56788,58078",
}

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/jobcode_assignments?ids=56788,58078"

  req, _ := http.NewRequest("DELETE", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/jobcode_assignments?ids=56788,58078")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "DELETE"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/jobcode_assignments?ids=56788,58078"; 

$client->DELETE($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

You can delete an existing object by sending an HTTP DELETE action to the resource's endpoint url. An HTTP DELETE is similar to a GET, where all relevant parameters are passed as part of a query string. You must include an identifying id of some sort for the object you would like to delete as part of your parameters.

Note: Some endpoints which do not support DELETE instead allow items to be "archived" (aka soft deleted). For example, you can make a PUT call with active=false to the Users endpoint to remove a user.

Possible HTTP Response Status Codes

2xx response codes

All 2xx response codes indicate that the request was successful. The response body contains any details for the action requested.

3xx response codes

All 3xx response codes indicate that you need to look elsewhere for your result. The response body will contain directions on where you should be redirected to.

4xx response codes

All 4xx response codes indicate failure for the action requested. Following are the most common 4xx response codes:

400 Bad Request There was something wrong with your request.
401 Unauthorized You don't have sufficient permission to perform the action you requested.
402 Billing not current Your account billing is not current, so access was denied.
405 Method Not Allowed The action you are trying to perform is not allowed.
409 Conflict There is a conflict with the operation you're trying to perform (details in the response body).
413 Max Items Exceeded The number of objects you are listing or editing or adding is too large.
417 Expectation Failed Your request was missing required parameters or your request was somehow otherwise malformed.
429 Too Many Requests You have sent too many requests to the API in too short a time. You'll have to try your requests again later.

5xx response codes

All 5xx response codes indicate a server error or exceptional condition on the TSheets side. Following are the most common 5xx response codes:

500 Internal Server Error There was an unspecified error on the TSheets side. Try your request again in a moment; if you receive the same error then wait a few minutes before repeating it, as we are probably working to correct it. If you continue to receive the error after several hours, contact us to report a bug.
501 Method not implemented This method is not implemented for this object. It may be in the future.
503 (Various messages) A 503 response code indicates that the service is temporarily unavailable. Wait a few minutes for the condition to clear, and try again.

_status_code's in the Response Body

Please note that the API will include a _status_code in the response body associated with each element that was passed in a POST or PUT request. These _status_code's will have similar values to the HTTP Response codes listed above, but they don't necessarily have the same meaning. You can find documentation on each _status_code that may be returned as part of each API endpoint's documentation.

Response Formats

Example

{
  "results": {
    "users": {
      "933849": {
        "id": 933849,
        "first_name": "Mary",
        "last_name": "Samsonite",
        "group_id": 0,
        "active": true,
        "employee_number": 0,
        "salaried": false,
        "exempt": false,
        "username": "admin",
        "email": "admin@example.com",
        "email_verified": false,
        "payroll_id": "",
        "mobile_number": "2087231456",
        "hire_date": "0000-00-00",
        "term_date": "0000-00-00",
        "last_modified": "2018-03-28T17:24:20+00:00",
        "last_active": "",
        "created": "2018-03-27T16:13:34+00:00",
        "client_url": "api_sample_output",
        "company_name": "API Sample Output Company",
        "profile_image_url": "https:\/\/www.gravatar.com\/avatar\/e64c7d89f26bd1972efa854d13d7dd61",
        "display_name": null,
        "pto_balances": {
          "2624351": 0,
          "2624353": 0,
          "2624355": 0
        },
        "submitted_to": "2000-01-01",
        "approved_to": "2000-01-01",
        "manager_of_group_ids": [ ],
        "require_password_change": false,
        "pay_rate": 0,
        "pay_interval": "hour",
        "permissions": {
          "admin": true,
          "mobile": true,
          "status_box": false,
          "reports": false,
          "manage_timesheets": false,
          "manage_authorization": false,
          "manage_users": false,
          "manage_my_timesheets": false,
          "manage_jobcodes": false,
          "pin_login": false,
          "approve_timesheets": false,
          "manage_schedules": false,
          "external_access": false,
          "manage_my_schedule": false,
          "manage_company_schedules": false,
          "view_company_schedules": false,
          "view_group_schedules": false,
          "manage_no_schedules": false,
          "view_my_schedules": false
        },
        "customfields": ""
      }
    }
  },
  "more": false,
  "supplemental_data": {
    "jobcodes": {
      "2624351": {
        "id": 2624351,
        "parent_id": 0,
        "assigned_to_all": true,
        "billable": false,
        "active": true,
        "type": "pto",
        ...
      },
      "2624353": {
        "id": 2624353,
        "parent_id": 0,
        "assigned_to_all": true,
        "billable": false,
        "active": true,
        "type": "pto",
        ...
      },
      "2624355": {
        "id": 2624355,
        "parent_id": 0,
        "assigned_to_all": true,
        "billable": false,
        "active": true,
        "type": "pto",
        ...
      }
    }
  }
}

TSheets returns resource representations as JSON, unless an exception occurs. Each JSON response object will contain the response data underneath an object property labeled 'results'.

For GET requests, in the response body there will also be a boolean with the name, "more". If true, it means that there is another page of objects that can be retrieved. Otherwise false will be the value.

If the resource object references any other objects via an id (i.e. group_id), a corresponding JSON representation of that object will be contained in another top level property labeled supplemental_data.

Exceptions

TSheets returns exceptions in the HTTP response body when something goes wrong. An exception has the following properties:

Property Description
code The HTTP status code for the exception.
message A descriptive message regarding the exception.

Tips & Suggestions

Requesting items that have changed since you last made a request to the API

When you are looking to see whether any items have changed since your last request, it is best to query the last_modified_timestamps API endpoint. This will allow you to easily make a single API query and see the most recent time any object from an endpoint was modified.

When you determine that you need to query an endpoint, use the modified_since parameter to get only those items that have been modified since the last time you made a request.

Working with Jobcodes & Jobcode Assignments

When working with Jobcodes it is highly recommended to use the Jobcode Assignments endpoint whenever possible in order to limit the number of jobcodes returned from a request. This becomes very important when dealing with TSheets accounts connected with external services such as Quickbooks since it is likely that the account will have a large number of Jobcodes.

Archiving objects no longer in use

To keep your account running as efficiently as possible, it is a good idea to archive certain objects once you are done with them. You can archive Users, Jobcodes, and Customfielditems when they're no longer actively being used. You do this by setting their active field to false. All of these items are still represented in reports, even though they're archived.

You cannot archive timesheets. If you delete a timesheet, it is permanently removed. To retain the ability to perform historical reporting on time, we recommend that you do not delete timesheets, unless it's for the purpose of correcting an inaccuracy.

Handling Supplemental Timesheet Data

Example: Suppemental Data.

Request

curl "https://rest.tsheets.com/api/v1/timesheets?start_date=12-05-2017&modified_since=12-05-2018" \
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/timesheets?start_date=12-05-2017&modified_since=12-05-2018");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/timesheets?start_date=12-05-2017&modified_since=12-05-2018")
Dim request = New RestRequest(Method.[GET])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/timesheets?start_date=12-05-2017&modified_since=12-05-2018")
  .get()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/timesheets?start_date=12-05-2017&modified_since=12-05-2018",
  "method": "GET",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'GET',
  url: 'https://rest.tsheets.com/api/v1/timesheets',
  qs: {
    start_date: '12-05-2017',
    modified_since: '12-05-2018',
  },
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/timesheets');
$request->setMethod(HTTP_METH_GET);

$request->setQueryData(array(
  'start_date' => '12-05-2017',
  'modified_since' => '12-05-2018',
));

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/timesheets?start_date=12-05-2017&modified_since=12-05-2018")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/timesheets"

querystring = {
  "start_date":"12-05-2017",
  "modified_since":"12-05-2018",
}

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/timesheets?start_date=12-05-2017&modified_since=12-05-2018"

  req, _ := http.NewRequest("GET", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/timesheets?start_date=12-05-2017&modified_since=12-05-2018")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest, completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/timesheets?start_date=12-05-2017&modified_since=12-05-2018"; 

$client->GET($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "timesheets": {
      "142835829": {
        "id": 142835829,
        "user_id": 1396641,
        "jobcode_id": 20355120,
        "start": "2018-07-23T10:00:00-07:00",
        "end": "2018-07-23T13:10:23-07:00",
        "duration": 11423,
        "date": "2018-07-23",
        "tz": -7,
        "tz_str": "",
        "type": "regular",
        "location": "TSheets API Tester",
        "active": "0",
        "locked": 0,
        "notes": "This is a test of the emergency broadcast system",
        "customfields": {
          "24068": "",
          "24066": ""
        },
        "last_modified": "2018-12-13T22:52:08+00:00"
      },
      "142835831": {
        "id": 142835831,
        "user_id": 1396641,
        "jobcode_id": 20347779,
        "start": "2018-07-25T09:30:00-07:00",
        "end": "2018-07-25T13:10:23-07:00",
        "duration": 13223,
        "date": "2018-07-25",
        "tz": -7,
        "tz_str": "",
        "type": "regular",
        "location": "TSheets API Tester",
        "active": "0",
        "locked": 0,
        "notes": "This is a test",
        "customfields": {
          "24068": "",
          "24066": ""
        },
        "last_modified": "2018-12-13T20:30:42+00:00"
      }
    }
  },
  "more": false,
  "supplemental_data": {
    "jobcodes": {
      "20355120": {
        "id": 20355120,
        "parent_id": 0,
        "assigned_to_all": true,
        "billable": false,
        "active": true,
        "type": "regular",
        ...
      },
      "20347779": {
        "id": 20347779,
        "parent_id": 0,
        "assigned_to_all": true,
        "billable": false,
        "active": true,
        "type": "regular",
        ...
      }
    },
    "users": {
      "1396641": {
        "id": 1396641,
        "first_name": "API",
        "last_name": "Employee",
        "group_id": 0,
        "active": true,
        ...
      }
    },
    "customfields": {
      "24068": {
        "id": 24068,
        "required": false,
        "applies_to": "timesheet",
        "type": "free-form",
        ...
      },
      "24066": {
        "id": 24066,
        "required": false,
        "applies_to": "timesheet",
        "type": "managed-list",
        ...
      }
    }
  }
}

When fetching timesheets via TSheets, supplemental data that is pertinent to the timesheets returned will be sent back in a supplemental_data JSON object unless you exclude it with an API filter. Within this object you will find additional objects related to the timesheets that were returned in the result set. In the example, Jobcode, User, and Custom Field objects are returned if they are referenced in the timesheet results. This is done specifically to ensure that API consumers have all the necessary data to display any timesheets that are returned. Knowing this, it is a best practice for API consumers to always parse and store any supplemental data should they wish to persist and display these timesheets later (for offline viewing, etc).

You can exclude supplemental data from GET requests for the timesheets and other endpoints by including the parameter supplemental_data with a value of "no". If your application will not be using the supplemental data from a given request, you can include this parameter to reduce payload size and improve the response time.

Recipes for Some Common Workflows

Getting current status of a single user (whether on or off the clock)

Query the timesheets endpoint for the given user with active status = true over the last 7 days.

/timesheets?user_ids=[USER_ID]&on_the_clock=yes&start_date=[7_DAYS_AGO]

This works because:

Getting current status and totals of all users (or one) in compact format

Query the /reports endpoint for the 'current_totals' report (this is what fuels our "who's working" window in the web dashboard). This will get you a tally of time for the day and the current task and whether or not each user is on the clock at the moment.

Approving time

A user may submit their time (if configured to allow it), while managers and admins may approve time. PUT to the Users endpoint, modifying the submitted_to and/or approved_to properties.

Running Payroll

If you have the Approvals Add-On installed, then each user will have a submitted_to and approved_to property. When you query the /reports endpoint for a payroll report - entries will reference a user_id which will correspond to an entry in the supplemental_data portion of the response. You can check the approved_to property of each user via the supplemental_data in the response.

We recommend that you do one of two things:

1) Only use payroll entries where the user's time has been approved.

OR

2) Use all payroll entries, but somehow distinguish (in the UI) between those who are approved versus those who are not.

Walkthroughs

Obtaining an API Access Token

This walkthrough will guide you through the process of creating an API App in TSheets and obtaining an API Access Token for use as the OAuth2 Bearer Token value in the Authentication header that is required when making a call to any of the API methods.

1) Install the API App Feature Add-On

Log into your TSheets Account and select the Feature Add-ons...Manage Add-ons... menu from the left navigation pane (actual menu layout may differ.)


2) Select the API Add-On and click Install

Afterwards, the API Add-On will be available from the Feature Add-ons section of the left navigation pane.


3) Add a New Application

Select Add a new application at bottom left. If the following window is not displayed, you can select API from Feature Add-ons on the left navigation pane.


4) Enter API Application Details

Add a short name and a meaningful description. For now, just use a dummy value for the Redirect URI. It can be edited later.


5) Create a New Token

Almost there! Click Add Token at bottom left. This step will generate a token for immediate use.


6) Capture the New Token Value for Use with the API

Copy the token value for use with API method calls, and be sure to Save before exiting. Congratulations! You may now explore the API with ease, fully authenticated.

End of Walkthrough.

Current User

The Current User Object

An instance of the User Object, but for the user associated with the current access token.

Retrieve the Current User

Example: Retrieve current user.

Request

curl "https://rest.tsheets.com/api/v1/current_user" \
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/current_user");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/current_user")
Dim request = New RestRequest(Method.[GET])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/current_user")
  .get()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/current_user",
  "method": "GET",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'GET',
  url: 'https://rest.tsheets.com/api/v1/current_user',
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/current_user');
$request->setMethod(HTTP_METH_GET);

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/current_user")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/current_user"

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/current_user"

  req, _ := http.NewRequest("GET", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/current_user")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest, completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/current_user"; 

$client->GET($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "users": {
      "933849": {
        "id": 933849,
        "first_name": "Mary",
        "last_name": "Samsonite",
        "group_id": 0,
        "active": true,
        "employee_number": 0,
        "salaried": false,
        "exempt": false,
        "username": "admin",
        "email": "admin@example.com",
        "email_verified": false,
        "payroll_id": "",
        "mobile_number": "2087231456",
        "hire_date": "0000-00-00",
        "term_date": "0000-00-00",
        "last_modified": "2018-03-28T17:24:20+00:00",
        "last_active": "",
        "created": "2018-03-27T16:13:34+00:00",
        "client_url": "api_sample_output",
        "company_name": "API Sample Output Company",
        "profile_image_url": "https:\/\/www.gravatar.com\/avatar\/e64c7d89f26bd1972efa854d13d7dd61",
        "display_name": null,
        "pto_balances": {
          "2624351": 0,
          "2624353": 0,
          "2624355": 0
        },
        "submitted_to": "2000-01-01",
        "approved_to": "2000-01-01",
        "manager_of_group_ids": [ ],
        "require_password_change": false,
        "pay_rate": 0,
        "pay_interval": "hour",
        "permissions": {
          "admin": true,
          "mobile": true,
          "status_box": false,
          "reports": false,
          "manage_timesheets": false,
          "manage_authorization": false,
          "manage_users": false,
          "manage_my_timesheets": false,
          "manage_jobcodes": false,
          "pin_login": false,
          "approve_timesheets": false,
          "manage_schedules": false,
          "external_access": false,
          "manage_my_schedule": false,
          "manage_company_schedules": false,
          "view_company_schedules": false,
          "view_group_schedules": false,
          "manage_no_schedules": false,
          "view_my_schedules": false
        },
        "customfields": ""
      }
    }
  },
  "more": false,
  "supplemental_data": {
    "jobcodes": {
      "2624351": {
        "id": 2624351,
        "parent_id": 0,
        "assigned_to_all": true,
        "billable": false,
        "active": true,
        "type": "pto",
        ...
      },
      "2624353": {
        "id": 2624353,
        "parent_id": 0,
        "assigned_to_all": true,
        "billable": false,
        "active": true,
        "type": "pto",
        ...
      },
      "2624355": {
        "id": 2624355,
        "parent_id": 0,
        "assigned_to_all": true,
        "billable": false,
        "active": true,
        "type": "pto",
        ...
      }
    }
  }
}

Retrieves the user object for the currently authenticated user. This is the user that authenticated to TSheets during the OAuth2 authentication process.

HTTP Request

gethttps://rest.tsheets.com/api/v1/current_user

Parameters

None

Custom Fields

Custom Fields (aka "Advanced Tracking") provide a means to extend the data that is tracked on employee time cards to capture custom activities beyond time tracking, e.g. mileage, equipment, expenses, etc. A maximum of 6 Custom Fields can be 'active' on an account at any given time.

The Custom Field Object

Example

{
  "id": 134913,
  "active": true,
  "required": true,
  "applies_to": "timesheet",
  "type": "managed-list",
  "short_code": "Exp",
  "regex_filter": "",
  "name": "Experience",
  "last_modified": "2019-02-10T20:40:41+00:00",
  "created": "2019-02-03T18:36:16+00:00",
  "ui_preference": "drop_down",
  "required_customfields": [],
  "show_to_all": false
}

Following is a list of the properties that belong to a customfield object, and a description of each.

id
read-only
Int Id of customfield.
active
read-write
Boolean true or false. If true, this custom field is active. If false, this custom field is archived.
name
read-write
String Name of the customfield.
short_code
read-write
String This is a shortened code or alias that is associated with the customfield. It may only consist of letters and numbers.
show_to_all
read-write
Boolean Declares whether this customfield should be shown on timesheets regardless of the jobcode chosen. If false, it will only appear when the chosen jobcode for a timesheet has been associated with this field. This field can only be set to false if the custom field is of type 'timesheet'.
required
read-write
Boolean true or false. Indicates whether a value for this customfield is required on a timesheet
applies_to
read-write
String 'timesheet' or 'user' or 'jobcode'. Indicates what type of object this customfield applies to.
type
read-only
String 'managed-list' or 'free-form'. If 'free-form', then it should be displayed in a UI as a text box, where users can enter values for this customfield and they'll get added automatically to the customfield if they don't already exist. If 'managed-list', then it should be displayed as a select-box and users can only choose an existing value.
ui_preference
read-only
String 'drop_down' or 'text_box_with_suggest'. Indicates the suggested user interface depending on the specified type.
regex_filter
read-only
String Regular expression that will be applied to any new items as they're added to the customfield. If they do not match the regex_filter, they may not be added.
last_modified
read-only
String Date/time when this customfield was last modified, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm).
created
read-only
String Date/time when this customfield was created, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm).
required_customfields
read-only
Array Ids of customfields that should be displayed when this customfield is visible on a timecard

Retrieve Custom Fields

Example: Retrieve a list of all customfields.

Request

curl "https://rest.tsheets.com/api/v1/customfields" \
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/customfields");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/customfields")
Dim request = New RestRequest(Method.[GET])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/customfields")
  .get()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/customfields",
  "method": "GET",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'GET',
  url: 'https://rest.tsheets.com/api/v1/customfields',
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/customfields');
$request->setMethod(HTTP_METH_GET);

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/customfields")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/customfields"

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/customfields"

  req, _ := http.NewRequest("GET", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/customfields")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest, completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/customfields"; 

$client->GET($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Example: Retrieve a list of customfields with a given id.

Request

curl "https://rest.tsheets.com/api/v1/customfields?ids=195923" \
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/customfields?ids=195923");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/customfields?ids=195923")
Dim request = New RestRequest(Method.[GET])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/customfields?ids=195923")
  .get()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/customfields?ids=195923",
  "method": "GET",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'GET',
  url: 'https://rest.tsheets.com/api/v1/customfields',
  qs: {
    ids: '195923',
  },
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/customfields');
$request->setMethod(HTTP_METH_GET);

$request->setQueryData(array(
  'ids' => '195923',
));

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/customfields?ids=195923")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/customfields"

querystring = {
  "ids":"195923",
}

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/customfields?ids=195923"

  req, _ := http.NewRequest("GET", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/customfields?ids=195923")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest, completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/customfields?ids=195923"; 

$client->GET($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Example: Retrieve a list of customfields that have been modified since a given date.

Request

curl "https://rest.tsheets.com/api/v1/customfields?modified_since=2018-01-01T00:00:00%2B00:00" \
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/customfields?modified_since=2018-01-01T00:00:00%2B00:00");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/customfields?modified_since=2018-01-01T00:00:00%2B00:00")
Dim request = New RestRequest(Method.[GET])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/customfields?modified_since=2018-01-01T00:00:00%2B00:00")
  .get()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/customfields?modified_since=2018-01-01T00:00:00%2B00:00",
  "method": "GET",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'GET',
  url: 'https://rest.tsheets.com/api/v1/customfields',
  qs: {
    modified_since: '2018-01-01T00:00:00%2B00:00',
  },
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/customfields');
$request->setMethod(HTTP_METH_GET);

$request->setQueryData(array(
  'modified_since' => '2018-01-01T00:00:00%2B00:00',
));

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/customfields?modified_since=2018-01-01T00:00:00%2B00:00")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/customfields"

querystring = {
  "modified_since":"2018-01-01T00:00:00%2B00:00",
}

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/customfields?modified_since=2018-01-01T00:00:00%2B00:00"

  req, _ := http.NewRequest("GET", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/customfields?modified_since=2018-01-01T00:00:00%2B00:00")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest, completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/customfields?modified_since=2018-01-01T00:00:00%2B00:00"; 

$client->GET($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "customfields": {
      "195923": {
        "id": 195923,
        "active": true,
        "required": true,
        "applies_to": "timesheet",
        "type": "managed-list",
        "short_code": "e",
        "regex_filter": "",
        "name": "Equipment",
        "last_modified": "2018-04-04T15:37:30+00:00",
        "created": "2018-03-27T16:13:35+00:00",
        "ui_preference": "drop_down",
        "required_customfields": [ ],
        "show_to_all": false
      },
      "195921": {
        "id": 195921,
        "active": true,
        "required": false,
        "applies_to": "timesheet",
        "type": "free-form",
        "short_code": "m",
        "regex_filter": "",
        "name": "Mood",
        "last_modified": "2018-03-27T16:13:35+00:00",
        "created": "2018-03-27T16:13:35+00:00",
        "ui_preference": "text_box_with_suggest",
        "required_customfields": [ ],
        "show_to_all": true
      },
      "195919": {
        "id": 195919,
        "active": true,
        "required": false,
        "applies_to": "timesheet",
        "type": "managed-list",
        "short_code": "w",
        "regex_filter": "",
        "name": "Work Type",
        "last_modified": "2018-03-27T16:13:35+00:00",
        "created": "2018-03-27T16:13:35+00:00",
        "ui_preference": "drop_down",
        "required_customfields": [ ],
        "show_to_all": true
      }
    }
  },
  "more": false
}

Retrieves a list of all customfields associated with your company, with optional filters to narrow down the results.

HTTP Request

gethttps://rest.tsheets.com/api/v1/customfields

Filter Parameters

ids
optional
Int Comma separated list of one or more customfield ids you'd like to filter on. Only customfields with an id set to one of these values will be returned. If omitted, all customfields matching other specified filters are returned.
active
optional
String 'yes', 'no', or 'both'. Default is 'yes'.
applies_to
optional
String 'timesheet', 'user', 'jobcode', or 'all'. Default is 'timesheet'.
value_type
optional
String 'managed-list', 'free-form', or 'both'. Default is 'both'.
modified_before
optional
String Only customfields modified before this date/time will be returned, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm).
modified_since
optional
String Only customfields modified since this date/time will be returned, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm).
supplemental_data
optional
String 'yes' or 'no'. Default is 'yes'. Indicates whether supplemental data should be returned.
per_page
optional
Int Deprecated. Use limit for new code.
Represents how many results you'd like to retrieve per request. Default is 50. Max is 50.
If a value over 50 is provided, it is ignored, and the max is used.
limit
optional
Int Represents how many results you'd like to retrieve per request. Default is 200. Max is 200.
If present, this value must be: an integer, greater than zero, and not greater than 200.
Setting limit less than 1 or greater than 200 will result in an error.
page
optional
Int Represents the page of results you'd like to retrieve. Default is 1.

Create Custom Fields

Example: Create a new customfield.

Request Body

{
 "data":
  [
    {
      "name": "Vehicle Number",
      "required": true,
      "active": true,
      "applies_to": "timesheet",
      "type": "managed-list",
      "show_to_all": true,
      "short_code": "vin"
    }
  ]
}


Request

curl -X POST \
  https://rest.tsheets.com/api/v1/customfields \
  -H 'Authorization: Bearer <TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '<REQUEST BODY>'
var client = new RestClient("https://rest.tsheets.com/api/v1/customfields");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <TOKEN>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "<REQUEST BODY>", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/customfields")
Dim request = New RestRequest(Method.POST)
request.AddHeader("Authorization", "Bearer <TOKEN>")
request.AddHeader("Content-Type", "application/json")
request.AddParameter("application/json", "<REQUEST BODY>", ParameterType.RequestBody);
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<REQUEST BODY>");
Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/customfields")
  .post(body)
  .addHeader("Authorization", "Bearer <TOKEN>")
  .addHeader("Content-Type", "application/json")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/customfields?modified_since=2018-01-01T00:00:00%2B00:00",
  "method": "POST",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
    "Content-Type", "application/json",
  },
  "processData": false,
  "data": "<REQUEST BODY>"
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'POST',
  url: 'https://rest.tsheets.com/api/v1/customfields',
  headers: 
  { 
     'Authorization': 'Bearer <TOKEN>',
     'Content-Type': 'application/json',
  },
  body: '<REQUEST BODY>',
  json: true };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/customfields');
$request->setMethod(HTTP_METH_POST);

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
  'Content-Type' => 'application/json',
));

$request->setBody('<REQUEST BODY>');

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/customfields")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <TOKEN>',
request["Content-Type"] = 'application/json',
request.body = "<REQUEST BODY>"

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/customfields"

payload = "<REQUEST BODY>"
headers = {
    'Authorization': 'Bearer <TOKEN>',
    'Content-Type': 'application/json',
    }

response = requests.request("POST", url, data=payload, headers=headers)

print(response.text)
package main

import (
  "fmt"
  "strings"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/customfields"

  payload := strings.NewReader("<REQUEST BODY>")

  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, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))

}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
   "Content-Type": "application/json",
]
let parameters = <REQUEST BODY> as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/customfields")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest,
  completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');
$client->addHeader('Content-Type', 'application/json');

$req = '<REQUEST BODY>';

$url="https://rest.tsheets.com/api/v1/customfields"; 

$client->POST($url, $req);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "customfields": {
      "1": {
        "_status_code": 200,
        "_status_message": "Created",
        "id": 1234567890,
        "name": "Vehicle Number",
        "required": true,
        "active": true,
        "applies_to": "timesheet",
        "type": "managed-list",
        "short_code": "vin",
        "regex_filter": "",
        "show_to_all": true,
        "last_modified": "2019-02-10T20:40:41+00:00",
        "created": "2019-02-10T20:40:41+00:00",
        "ui_preference": "dropdown",
        "required_customfields": [],
        "show_to_all": true
      }
    }
  }
}

Add one or more customfields.

HTTP Request

posthttps://rest.tsheets.com/api/v1/customfields

Properties

Pass an array of customfield objects as the value to a 'data' property (see example).

name
required
String The name of this customfield.
required
optional
Boolean Default: false. If true, a non-null value must be selected for this customfield when it appears on a timesheet.
active
optional
Boolean Default: true. If false, this customfield is considered archived and will not be visible or usable.
applies_to
required
String Default: timesheet. Allowed values: 'timesheet'. Specify that this customfield should appear on timesheets (additional customfield types may be supported in the future).
type
required
String Allowed values: 'managed-list', 'free-form'. A managed-list customfield is intended to be displayed as a dropdown list, where each 'option' is a customfielditem. A 'free-form' customfield supports text entry and does not require a collection of customfielditems to accompany it.
show_to_all
optional
Boolean Default: false. Declares whether this customfield should be shown on timesheets regardless of the jobcode chosen. If false, it will only appear when the chosen jobcode for a timesheet has been associated with this field.
short_code
optional
String Default: "" (none). This is a shortened code or alias that is associated with the customfield. It may only consist of letters and numbers. If not provided, an alias will be auto-generated.

For a full list of the properties that may be set on a customfield, see The Custom Field Object.

Status Codes

Each customfield that is created will come back with a _status_code and _status_message that will indicate whether the customfield was created successfully. If there was a problem creating a customfield, there may also be an additional field, _status_extra, which will contain more details about the failure.

200 OK. customfield was created successfully.
417 Expectation Failed. Something was wrong or missing with the properties supplied for this customfield. See the _status_extra value for more detail.

Update Custom Fields

Example: Change some information for each of these customfields. The first customfield will have its name changed. The second field is being archived by setting active to false.

Request Body

{
 "data":
  [
    {
      "id":19142,
      "name":"Vehicle"
    },
    {
      "id":21889,
      "active":false,
    }
  ]
}

Request

curl -X PUT \
  https://rest.tsheets.com/api/v1/customfields \
  -H 'Authorization: Bearer <TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '<REQUEST BODY>'
var client = new RestClient("https://rest.tsheets.com/api/v1/customfields");
var request = new RestRequest(Method.PUT);
request.AddHeader("Authorization", "Bearer <TOKEN>");
request.AddHeader("Content-Type", "application/json");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/customfields")
Dim request = New RestRequest(Method.PUT)
request.AddHeader("Authorization", "Bearer <TOKEN>")
request.AddHeader("Content-Type", "application/json")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<REQUEST BODY>");
Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/customfields")
  .put(body)
  .addHeader("Authorization", "Bearer <TOKEN>")
  .addHeader("Content-Type", "application/json")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/customfields?modified_since=2018-01-01T00:00:00%2B00:00",
  "method": "PUT",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
    "Content-Type", "application/json",
  },
  "processData": false,
  "data": "<REQUEST BODY>"
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'PUT',
  url: 'https://rest.tsheets.com/api/v1/customfields',
  headers: 
  { 
     'Authorization': 'Bearer <TOKEN>',
     'Content-Type': 'application/json',
  },
  body: '<REQUEST BODY>',
  json: true };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/customfields');
$request->setMethod(HTTP_METH_PUT);

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
  'Content-Type' => 'application/json',
));

$request->setBody('<REQUEST BODY>');

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/customfields")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <TOKEN>',
request["Content-Type"] = 'application/json',
request.body = "<REQUEST BODY>"

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/customfields"

payload = "<REQUEST BODY>"
headers = {
    'Authorization': 'Bearer <TOKEN>',
    'Content-Type': 'application/json',
    }

response = requests.request("PUT", url, data=payload, headers=headers)

print(response.text)
package main

import (
  "fmt"
  "strings"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/customfields"

  payload := strings.NewReader("<REQUEST BODY>")

  req, _ := http.NewRequest("PUT", 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, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))

}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
   "Content-Type": "application/json",
]
let parameters = <REQUEST BODY> as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(
  url: NSURL(string: "http://rest.tsheets.com/api/v1/customfields")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "PUT"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest,
  completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');
$client->addHeader('Content-Type', 'application/json');

$req = '<REQUEST BODY>';

$url="http://rest.tsheets.com/api/v1/customfields"; 

$client->PUT($url, $req);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "customfields": {
      "1": {
        "_status_code": 200,
        "_status_message": "Updated",
        "id": 19142,
        "name": "Vehicle",
        "required": true,
        "active": true,
        "applies_to": "timesheet",
        "type": "managed-list",
        "short_code": "vin",
        "regex_filter": "",
        "show_to_all": true,
        "last_modified": "2019-11-03T16:05:10+00:00",
        "created": "2019-02-10T20:40:41+00:00",
        "ui_preference": "dropdown",
        "required_customfields": [],
        "show_to_all": true
      },
      "2": {
        "_status_code": 200,
        "_status_message": "Updated",
        "id": 21889,
        "name": "Task",
        "required": true,
        "active": false,
        "applies_to": "timesheet",
        "type": "managed-list",
        "short_code": "t",
        "regex_filter": "",
        "show_to_all": true,
        "last_modified": "2019-11-03T16:05:10+00:00",
        "created": "2019-02-10T20:40:41+00:00",
        "ui_preference": "dropdown",
        "required_customfields": [],
        "show_to_all": true
      }
    }
  }
}


Edit one or more customfields.

HTTP Request

puthttps://rest.tsheets.com/api/v1/customfields

Properties

Pass an array of customfield objects as the value to a 'data' property (see example).

id
required
Int Id of the customfield.

All other read-write properties defined on a Custom Field object may be passed in to the request with a new value in order to change it. If the value passed in is the same as it was previously, or if a particular property is not passed in at all, it will be ignored.

Note: The required_customfields property can't be modified through the API, but can be modified through the TSheets web app when logged in as an admin user.

Status Codes

Each customfield that is edited will come back with a _status_code and _status_message that will indicate whether the customfield was edited successfully. If there was a problem editing a customfield, there may also be an additional field, _status_extra, which will contain more details about the failure.

200 OK. Customfield was edited successfully.
417 Expectation Failed. Something was wrong or missing with the properties supplied for this customfield. See the _status_extra value for more detail.

Custom Field Items

A Custom Field Item represents an allowable value for a Custom Field Object of managed-list type. Each item represents a single drop-down choice displayed to the user in the web UI. The API provides methods to Create, Read, and Update custom field items. Set the active property false to archive (i.e. soft delete) a custom field item.

The Custom Field Item Object

Example

{
  "id": 3875655,
  "customfield_id": 143369,
  "active": true,
  "short_code": "JS",
  "name": "Jungle Safari",
  "last_modified": "2019-02-11T17:42:45+00:00",
  "required_customfields": []
}

Following is a list of the properties that belong to a customfield object, and a description of each.

id
read-only
Int Id of customfielditem.
customfield_id
read-only
Int Id for the customfield that this item belongs to.
name
read-write
String Name of the customfielditem.
short_code
read-write
String This is a short alias that is associated with the customfielditem. It may only consist of letters and numbers. Note: Custom Field Item short_code values must be unique for each TSheets account.
active
read-write
Boolean true or false. If false, the customfielditem is considered archived.
last_modified
read-only
String Date/time when this customfielditem was last modified, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm).
required_customfields
read-only
Int[] Ids of customfields that should be displayed when this customfielditem is selected on a timecard.

Retrieve Custom Field Items

Example: Retrieve a list of all active customfielditems belonging to the given customfield.

Request

curl "https://rest.tsheets.com/api/v1/customfielditems?customfield_id=195923" \
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/customfielditems?customfield_id=195923");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/customfielditems?customfield_id=195923")
Dim request = New RestRequest(Method.[GET])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/customfielditems?customfield_id=195923")
  .get()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/customfielditems?customfield_id=195923",
  "method": "GET",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'GET',
  url: 'https://rest.tsheets.com/api/v1/customfielditems',
  qs: {
    customfield_id: '195923',
  },
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/customfielditems');
$request->setMethod(HTTP_METH_GET);

$request->setQueryData(array(
  'customfield_id' => '195923',
));

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/customfielditems?customfield_id=195923")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/customfielditems"

querystring = {
  "customfield_id":"195923",
}

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/customfielditems?customfield_id=195923"

  req, _ := http.NewRequest("GET", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/customfielditems?customfield_id=195923")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest, completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/customfielditems?customfield_id=195923"; 

$client->GET($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Example: Retrieve a list of all customfielditems (active or deleted) belonging to the given customfield, and set pagination to 10 results/page.

Request

curl "https://rest.tsheets.com/api/v1/customfielditems?customfield_id=195923&limit=10&active=both" \
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/customfielditems?customfield_id=195923&limit=10&active=both");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/customfielditems?customfield_id=195923&limit=10&active=both")
Dim request = New RestRequest(Method.[GET])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/customfielditems?customfield_id=195923&limit=10&active=both")
  .get()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/customfielditems?customfield_id=195923&limit=10&active=both",
  "method": "GET",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'GET',
  url: 'https://rest.tsheets.com/api/v1/customfielditems',
  qs: {
    customfield_id: '195923',
    limit: '10',
    active: 'both',
  },
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/customfielditems');
$request->setMethod(HTTP_METH_GET);

$request->setQueryData(array(
  'customfield_id' => '195923',
  'limit' => '10',
  'active' => 'both',
));

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/customfielditems?customfield_id=195923&limit=10&active=both")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/customfielditems"

querystring = {
  "customfield_id":"195923",
  "limit":"10",
  "active":"both",
}

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/customfielditems?customfield_id=195923&limit=10&active=both"

  req, _ := http.NewRequest("GET", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/customfielditems?customfield_id=195923&limit=10&active=both")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest, completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/customfielditems?customfield_id=195923&limit=10&active=both"; 

$client->GET($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Example: Retrieve a list of customfielditems belonging to the given customfield and having given ids.

Request

curl "https://rest.tsheets.com/api/v1/customfielditems?customfield_id=195923&ids=3875655,3875657" \
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/customfielditems?customfield_id=195923&ids=3875655,3875657");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/customfielditems?customfield_id=195923&ids=3875655,3875657")
Dim request = New RestRequest(Method.[GET])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/customfielditems?customfield_id=195923&ids=3875655,3875657")
  .get()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/customfielditems?customfield_id=195923&ids=3875655,3875657",
  "method": "GET",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'GET',
  url: 'https://rest.tsheets.com/api/v1/customfielditems',
  qs: {
    customfield_id: '195923',
    ids: '3875655,3875657',
  },
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/customfielditems');
$request->setMethod(HTTP_METH_GET);

$request->setQueryData(array(
  'customfield_id' => '195923',
  'ids' => '3875655,3875657',
));

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/customfielditems?customfield_id=195923&ids=3875655,3875657")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/customfielditems"

querystring = {
  "customfield_id":"195923",
  "ids":"3875655,3875657",
}

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/customfielditems?customfield_id=195923&ids=3875655,3875657"

  req, _ := http.NewRequest("GET", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/customfielditems?customfield_id=195923&ids=3875655,3875657")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest, completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/customfielditems?customfield_id=195923&ids=3875655,3875657"; 

$client->GET($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Example: Retrieve a list of customfielditems belonging to a given customfield that have been modified since a particular date.

Request

curl "https://rest.tsheets.com/api/v1/customfielditems?customfield_id=195923&modified_since=2018-01-01T00:00:00-06:00" \
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/customfielditems?customfield_id=195923&modified_since=2018-01-01T00:00:00-06:00");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/customfielditems?customfield_id=195923&modified_since=2018-01-01T00:00:00-06:00")
Dim request = New RestRequest(Method.[GET])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/customfielditems?customfield_id=195923&modified_since=2018-01-01T00:00:00-06:00")
  .get()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/customfielditems?customfield_id=195923&modified_since=2018-01-01T00:00:00-06:00",
  "method": "GET",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'GET',
  url: 'https://rest.tsheets.com/api/v1/customfielditems',
  qs: {
    customfield_id: '195923',
    modified_since: '2018-01-01T00:00:00-06:00',
  },
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/customfielditems');
$request->setMethod(HTTP_METH_GET);

$request->setQueryData(array(
  'customfield_id' => '195923',
  'modified_since' => '2018-01-01T00:00:00-06:00',
));

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/customfielditems?customfield_id=195923&modified_since=2018-01-01T00:00:00-06:00")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/customfielditems"

querystring = {
  "customfield_id":"195923",
  "modified_since":"2018-01-01T00:00:00-06:00",
}

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/customfielditems?customfield_id=195923&modified_since=2018-01-01T00:00:00-06:00"

  req, _ := http.NewRequest("GET", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/customfielditems?customfield_id=195923&modified_since=2018-01-01T00:00:00-06:00")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest, completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/customfielditems?customfield_id=195923&modified_since=2018-01-01T00:00:00-06:00"; 

$client->GET($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Example: Retrieve a list of customfielditems belonging to a given customfield and using the name wildcard, end in the given string.

Request

curl "https://rest.tsheets.com/api/v1/customfielditems?customfield_id=195923&name=*ate" \
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/customfielditems?customfield_id=195923&name=*ate");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/customfielditems?customfield_id=195923&name=*ate")
Dim request = New RestRequest(Method.[GET])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/customfielditems?customfield_id=195923&name=*ate")
  .get()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/customfielditems?customfield_id=195923&name=*ate",
  "method": "GET",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'GET',
  url: 'https://rest.tsheets.com/api/v1/customfielditems',
  qs: {
    customfield_id: '195923',
    name: '*ate',
  },
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/customfielditems');
$request->setMethod(HTTP_METH_GET);

$request->setQueryData(array(
  'customfield_id' => '195923',
  'name' => '*ate',
));

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/customfielditems?customfield_id=195923&name=*ate")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/customfielditems"

querystring = {
  "customfield_id":"195923",
  "name":"*ate",
}

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/customfielditems?customfield_id=195923&name=*ate"

  req, _ := http.NewRequest("GET", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/customfielditems?customfield_id=195923&name=*ate")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest, completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/customfielditems?customfield_id=195923&name=*ate"; 

$client->GET($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "customfielditems": {
      "1080235": {
        "id": 1080235,
        "customfield_id": 195923,
        "active": true,
        "short_code": "",
        "name": "Bazooka",
        "last_modified": "2018-03-27T16:13:35+00:00",
        "required_customfields": [ ]
      },
      "1080237": {
        "id": 1080237,
        "customfield_id": 195923,
        "active": true,
        "short_code": "",
        "name": "Shovel",
        "last_modified": "2018-03-27T16:13:35+00:00",
        "required_customfields": [ ]
      },
      "1080233": {
        "id": 1080233,
        "customfield_id": 195923,
        "active": true,
        "short_code": "",
        "name": "Tractor",
        "last_modified": "2018-03-27T16:13:35+00:00",
        "required_customfields": [ ]
      }
    }
  },
  "more": false,
  "supplemental_data": {
    "customfields": {
      "195923": {
        "id": 195923,
        "active": true,
        "required": true,
        "applies_to": "timesheet",
        "type": "managed-list",
        "short_code": "e",
        "regex_filter": "",
        "name": "Equipment",
        "last_modified": "2018-04-04T16:04:00+00:00",
        "created": "2018-03-27T16:13:35+00:00",
        "ui_preference": "drop_down",
        "required_customfields": [ ],
        "show_to_all": true
      }
    }
  }
}

Retrieves a list of all customfielditems associated with a customfield, with optional filters to narrow down the results.

HTTP Request

gethttps://rest.tsheets.com/api/v1/customfielditems

Filter Parameters

customfield_id
required
Int Id of the custom field whose items you'd like to list.
ids
optional
Int Comma separated list of one or more customfielditem ids you'd like to filter on. Only customfielditems with an id set to one of these values will be returned. If omitted, all customfielditems matching other specified filters are returned.
active
optional
String 'yes', 'no', or 'both'. Default is 'yes'. If a customfielditem is active, it is available for selection during time entry.
name
optional
String * will be interpreted as a wild card. Starts matching from the beginning of the string.
modified_before
optional
String Only customfielditems modified before this date/time will be returned, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm).
modified_since
optional
String Only customfielditems modified since this date/time will be returned, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm).
supplemental_data
optional
String 'yes' or 'no'. Default is 'yes'. Indicates whether supplemental data should be returned.
per_page
optional
Int Deprecated. Use limit for new code.
Represents how many results you'd like to retrieve per request. Default is 50. Max is 50.
If a value over 50 is provided, it is ignored, and the max is used.
limit
optional
Int Represents how many results you'd like to retrieve per request. Default is 200. Max is 200.
If present, this value must be: an integer, greater than zero, and not greater than 200.
Setting limit less than 1 or greater than 200 will result in an error.
page
optional
Int Represents the page of results you'd like to retrieve. Default is 1.

Create Custom Field Items

Example: Create two new customfielditems. One succeeds. The other fails because of a duplicate short_code on an existing customfielditem.

Request Body

{
 "data":
  [
    {
      "name":"ServiceItem1",
      "customfield_id":"19142",
      "short_code":"c1"
    },
    {
      "name":"ServiceItem2",
      "customfield_id":"19142",
      "short_code":"c1"
    }
  ]
}

Request

curl -X POST \
  https://rest.tsheets.com/api/v1/customfielditems \
  -H 'Authorization: Bearer <TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '<REQUEST BODY>'
var client = new RestClient("https://rest.tsheets.com/api/v1/customfielditems");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <TOKEN>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "<REQUEST BODY>", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/customfielditems")
Dim request = New RestRequest(Method.POST)
request.AddHeader("Authorization", "Bearer <TOKEN>")
request.AddHeader("Content-Type", "application/json")
request.AddParameter("application/json", "<REQUEST BODY>", ParameterType.RequestBody);
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<REQUEST BODY>");
Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/customfielditems")
  .post(body)
  .addHeader("Authorization", "Bearer <TOKEN>")
  .addHeader("Content-Type", "application/json")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/customfielditems?customfield_id=195923&name=*ate",
  "method": "POST",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
    "Content-Type", "application/json",
  },
  "processData": false,
  "data": "<REQUEST BODY>"
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'POST',
  url: 'https://rest.tsheets.com/api/v1/customfielditems',
  headers: 
  { 
     'Authorization': 'Bearer <TOKEN>',
     'Content-Type': 'application/json',
  },
  body: '<REQUEST BODY>',
  json: true };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/customfielditems');
$request->setMethod(HTTP_METH_POST);

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
  'Content-Type' => 'application/json',
));

$request->setBody('<REQUEST BODY>');

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/customfielditems")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <TOKEN>',
request["Content-Type"] = 'application/json',
request.body = "<REQUEST BODY>"

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/customfielditems"

payload = "<REQUEST BODY>"
headers = {
    'Authorization': 'Bearer <TOKEN>',
    'Content-Type': 'application/json',
    }

response = requests.request("POST", url, data=payload, headers=headers)

print(response.text)
package main

import (
  "fmt"
  "strings"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/customfielditems"

  payload := strings.NewReader("<REQUEST BODY>")

  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, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))

}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
   "Content-Type": "application/json",
]
let parameters = <REQUEST BODY> as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/customfielditems")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest,
  completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');
$client->addHeader('Content-Type', 'application/json');

$req = '<REQUEST BODY>';

$url="https://rest.tsheets.com/api/v1/customfielditems"; 

$client->POST($url, $req);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "customfielditems": {
      "1": {
        "_status_code": 200,
        "_status_message": "Created",
        "id": 3085864,
        "customfield_id": 19142,
        "active": true,
        "short_code": "c1",
        "name": "ServiceItem1"
      },
      "2": {
        "_status_code": 417,
        "_status_message": "Expectation Failed",
        "_status_extra": "Oops! The name or alias conflicts with another item named \"ServiceItem1\". Try choosing another name\/alias or deleting the other conflicting item first",
        "name": "ServiceItem2"
      }
    }
  },
  "supplemental_data": {
    "customfields": {
      "19142": {
        "id": 19142,
        "required": true,
        "type": "timesheet",
        "ui_preference": "managed-list",
        "short_code": "cf1",
        "regex_filter": "",
        "name": "Custom Field 1",
        "last_modified": "2018-07-23T23:09:14+00:00",
        "created": "2018-07-23T23:09:14+00:00"
      }
    }
  }
}

Add one or more customfielditems to a customfield.

HTTP Request

posthttps://rest.tsheets.com/api/v1/customfielditems

Properties

Pass an array of customfielditem objects as the value to a 'data' property (see example).

name
required
String Name of the customfielditem.
customfield_id
required
Int The id of the customfield you want this item to belong to.

For a full list of the properties that may be set on a customfielditem, see The Custom Field Item Object.

Status Codes

Each customfielditem that is created will come back with a _status_code and _status_message that will indicate whether the customfielditem was created successfully. If there was a problem creating a customfielditem, there may also be an additional field, _status_extra, which will contain more details about the failure.

200 OK. customfielditem was created successfully.
417 Expectation Failed. Something was wrong or missing with the properties supplied for this customfielditem. See the _status_extra value for more detail.

Update Custom Field Items

Example: Change some information for each of these customfielditems.

Request Body

{
 "data":
  [
    {
      "id":3085064,
      "customfield_id":19142,
      "active":true,
      "short_code":"por",
      "name":"Porsche"
    },
    {
      "id":3085066,
      "customfield_id":19142,
      "active":false,
      "short_code":"merc",
      "name":"Mercruiser"
    }
  ]
}

Request

curl -X PUT \
  https://rest.tsheets.com/api/v1/customfielditems \
  -H 'Authorization: Bearer <TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '<REQUEST BODY>'
var client = new RestClient("https://rest.tsheets.com/api/v1/customfielditems");
var request = new RestRequest(Method.PUT);
request.AddHeader("Authorization", "Bearer <TOKEN>");
request.AddHeader("Content-Type", "application/json");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/customfielditems")
Dim request = New RestRequest(Method.PUT)
request.AddHeader("Authorization", "Bearer <TOKEN>")
request.AddHeader("Content-Type", "application/json")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<REQUEST BODY>");
Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/customfielditems")
  .put(body)
  .addHeader("Authorization", "Bearer <TOKEN>")
  .addHeader("Content-Type", "application/json")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/customfielditems?customfield_id=195923&name=*ate",
  "method": "PUT",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
    "Content-Type", "application/json",
  },
  "processData": false,
  "data": "<REQUEST BODY>"
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'PUT',
  url: 'https://rest.tsheets.com/api/v1/customfielditems',
  headers: 
  { 
     'Authorization': 'Bearer <TOKEN>',
     'Content-Type': 'application/json',
  },
  body: '<REQUEST BODY>',
  json: true };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/customfielditems');
$request->setMethod(HTTP_METH_PUT);

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
  'Content-Type' => 'application/json',
));

$request->setBody('<REQUEST BODY>');

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/customfielditems")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <TOKEN>',
request["Content-Type"] = 'application/json',
request.body = "<REQUEST BODY>"

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/customfielditems"

payload = "<REQUEST BODY>"
headers = {
    'Authorization': 'Bearer <TOKEN>',
    'Content-Type': 'application/json',
    }

response = requests.request("PUT", url, data=payload, headers=headers)

print(response.text)
package main

import (
  "fmt"
  "strings"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/customfielditems"

  payload := strings.NewReader("<REQUEST BODY>")

  req, _ := http.NewRequest("PUT", 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, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))

}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
   "Content-Type": "application/json",
]
let parameters = <REQUEST BODY> as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(
  url: NSURL(string: "http://rest.tsheets.com/api/v1/customfielditems")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "PUT"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest,
  completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');
$client->addHeader('Content-Type', 'application/json');

$req = '<REQUEST BODY>';

$url="http://rest.tsheets.com/api/v1/customfielditems"; 

$client->PUT($url, $req);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "customfielditems": {
      "1": {
        "_status_code": 200,
        "_status_message": "Updated",
        "id": 3085064,
        "customfield_id": 19142,
        "active": true,
        "short_code": "por",
        "name": "Porsche"
      },
      "2": {
        "_status_code": 200,
        "_status_message": "Updated",
        "id": 3085066,
        "customfield_id": 19142,
        "active": false,
        "short_code": "merc",
        "name": "Mercruiser"
      }
    }
  },
  "supplemental_data": {
    "customfields": {
      "19142": {
        "id": 19142,
        "required": true,
        "type": "timesheet",
        "ui_preference": "managed-list",
        "short_code": "cf1",
        "regex_filter": "",
        "name": "Custom Field 1",
        "last_modified": "2018-07-23T23:09:14+00:00",
        "created": "2018-07-23T23:09:14+00:00",
        "required_customfields": [],
        "show_to_all": false
      }
    }
  }
}


Edit one or more customfielditems for a customfield.

HTTP Request

puthttps://rest.tsheets.com/api/v1/customfielditems

Properties

Pass an array of customfielditem objects as the value to a 'data' property (see example).

id
required
Int Id of the customfielditem.

All other properties defined on a Custom Field Item object may be passed in to the request with a new value in order to change it. If the value passed in is the same as it was previously, or if a particular property is not passed in at all, it will be ignored.

Status Codes

Each customfielditem that is edited will come back with a _status_code and _status_message that will indicate whether the customfielditem was edited successfully. If there was a problem editing a customfielditem, there may also be an additional field, _status_extra, which will contain more details about the failure.

200 OK. Customfielditem was edited successfully.
417 Expectation Failed. Something was wrong or missing with the properties supplied for this customfielditem. See the _status_extra value for more detail.

Custom Field Item Filters

The Item Filter Object

Example

{
  "id": 861013,
  "active": true,
  "applies_to": "jobcodes",
  "applies_to_id": 1883683,
  "customfielditem_id": 703671,
  "customfield_id": 117893,
  "last_modified": "2018-07-17T23:40:51+00:00"
}

Following is a list of the properties that belong to a customfielditem_filter object, and a description of each.

id
read-only
Int Id of customfielditem_filter.
customfield_id
read-write
Int Id for the customfield that this filter belongs to.
customfielditem_id
read-write
Int Id for the customfielditem that this filter belongs to.
applies_to
read-write
String Entity type this filter relates to. Together with applies_to_id, determines what this filtered item relates to. The possible values are: 'jobcodes', 'users', or 'groups'. For example: If this value was 'jobcodes' then the applies_to_id value would indicate which jobcode this filter referred to. If requested, the supplemental data will also contain this jobcode.
applies_to_id
read-write
Int The jobcode, user, or group that this filter relates to. Together with applies_to, determines what this filtered item relates to. For example: If the value of the applies_to field was 'jobcodes' this value would indicate which jobcode this filter referred to. If requested, the supplemental data will also contain this jobcode.
active
read-write
Boolean true or false. If false, this customfielditem_filter is considered archived or deleted.
last_modified
read-only
String Date/time when this customfielditem_filter was last modified, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm).

Retrieve Item Filters

Example: Retrieve a list of all customfielditem_filters modified since a given date/time.

Request

curl "https://rest.tsheets.com/api/v1/customfielditem_filters?modified_since=2018-07-17T00:00:00-00:00" \
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/customfielditem_filters?modified_since=2018-07-17T00:00:00-00:00");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/customfielditem_filters?modified_since=2018-07-17T00:00:00-00:00")
Dim request = New RestRequest(Method.[GET])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/customfielditem_filters?modified_since=2018-07-17T00:00:00-00:00")
  .get()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/customfielditem_filters?modified_since=2018-07-17T00:00:00-00:00",
  "method": "GET",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'GET',
  url: 'https://rest.tsheets.com/api/v1/customfielditem_filters',
  qs: {
    modified_since: '2018-07-17T00:00:00-00:00',
  },
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/customfielditem_filters');
$request->setMethod(HTTP_METH_GET);

$request->setQueryData(array(
  'modified_since' => '2018-07-17T00:00:00-00:00',
));

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/customfielditem_filters?modified_since=2018-07-17T00:00:00-00:00")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/customfielditem_filters"

querystring = {
  "modified_since":"2018-07-17T00:00:00-00:00",
}

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/customfielditem_filters?modified_since=2018-07-17T00:00:00-00:00"

  req, _ := http.NewRequest("GET", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/customfielditem_filters?modified_since=2018-07-17T00:00:00-00:00")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest, completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/customfielditem_filters?modified_since=2018-07-17T00:00:00-00:00"; 

$client->GET($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "customfielditem_filters": {
      "861013": {
        "id": 861013,
        "active": true,
        "applies_to": "jobcodes",
        "applies_to_id": 1883683,
        "customfielditem_id": 703671,
        "customfield_id": 117893,
        "last_modified": "2018-07-17T23:40:51+00:00"
      },
      "861015": {
        "id": 861015,
        "active": true,
        "applies_to": "users",
        "applies_to_id": 933849,
        "customfielditem_id": 703671,
        "customfield_id": 117893,
        "last_modified": "2018-07-17T23:40:51+00:00"
      },
      "861017": {
        "id": 861017,
        "active": true,
        "applies_to": "groups",
        "applies_to_id": 90443,
        "customfielditem_id": 703671,
        "customfield_id": 117893,
        "last_modified": "2018-07-17T23:40:51+00:00"
      }
    }
  },
  "more": false,
  "supplemental_data": {
    "jobcodes": {
      "1883683": {
        "id": 1883683,
        "active": true,
        "parent_id": 0,
        "assigned_to_all": true,
        "type": "pto",
        "billable": false,
        "billable_rate": 0,
        "short_code": "",
        "name": "Holiday",
        "created": "2017-08-28T15:57:15+0000",
        "last_modified": "2018-07-17T23:40:51+0000",
        "has_children": false,
        "required_customfields": [ ],
        "filtered_customfielditems": {
          "117893": [
            703671
          ]
        },
        "locations": [ ]
      }
    },
    "customfields": {
      "117893": {
        "id": 117893,
        "active": true,
        "name": "Fruit",
        "short_code": "fr",
        "required": 0,
        "applies_to": "timesheet",
        "type": "managed-list",
        "regex_filter": "",
        "last_modified": "2018-07-17T21:35:07+00:00",
        "created": "2017-08-30T16:12:52+00:00",
        "ui_preference": "drop_down",
        "required_customfields": [ ]
      }
    },
    "customfielditems": {
      "703671": {
        "id": 703671,
        "active": true,
        "name": "banana",
        "short_code": "",
        "customfield_id": 117893,
        "last_modified": "2018-07-17T21:35:07+00:00",
        "required_customfields": [ ]
      }
    },
    "users": {
      "933849": {
        "id": 933849,
        "first_name": "Mary",
        "last_name": "Samsonite",
        "group_id": 0,
        "active": true,
        ...
      }
    },
    "groups": {
      "90443": {
        "id": 90443,
        "active": true,
        "name": "customfielditem_filter_test_group",
        ...
      }
    }
  }
}

Retrieves a list of all customfielditem_filters associated with a jobcode, user, or group with options to narrow down the results.

Custom field item filters are used to limit the choices that should be made available for selecting customfielditems for a particular customfield based on a user or selected jobcode. If filtered items exist for a given user, user's group, or jobcode, the choices for the indicated customfield should be limited to those customfielditems only.

Please note that users can belong to groups and that groups can have filtered items. When requesting filtered items for a user, you can pass the 'include_user_group' option to return the customfielditem_filters for both the user and their assigned group.

HTTP Request

gethttps://rest.tsheets.com/api/v1/customfielditem_filters

Filter Parameters

jobcode_id
optional
Int Limits the returned filters to only those for the specified jobcode_id.
user_id
optional
Int Limits the returned filters to only those for the specified user_id. You can also include items for this user's group automatically if you include the 'include_user_group' parameter.
group_id
optional
Int Limits the returned filters to only those for the specified group_id.
include_user_group
optional
Boolean true or false. If a user_id is supplied, will return filters for that user's group as well.
include_jobcode_filters
optional
Boolean true or false. If a user_id is supplied, will additionally return jobcode filters.
ids
optional
Int Comma separated list of one or more customfielditem_filter ids you'd like to filter on. Only customfielditem_filters with an id set to one of these values will be returned. If omitted, all customfielditem_fields matching other specified filters are returned.
active
optional
String 'yes', 'no', or 'both'. Default is 'yes'. If a customfielditem_filter is inactive, it can be safely ignored.
modified_before
optional
String Only customfielditem_filters modified before this date/time will be returned, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm).
modified_since
optional
String Only customfielditem_filters modified since this date/time will be returned, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm).
supplemental_data
optional
String 'yes' or 'no'. Default is 'yes'. Indicates whether supplemental data should be returned.
per_page
optional
Int Deprecated. Use limit for new code.
Represents how many results you'd like to retrieve per request. Default is 50. Max is 50.
If a value over 50 is provided, it is ignored, and the max is used.
limit
optional
Int Represents how many results you'd like to retrieve per request. Default is 200. Max is 200.
If present, this value must be: an integer, greater than zero, and not greater than 200.
Setting limit less than 1 or greater than 200 will result in an error.
page
optional
Int Represents the page of results you'd like to retrieve. Default is 1.

Create Item Filters

Example: Create two new customfielditemfilters. One succeeds. The other fails because of an invalid applies_to.

Request Body

{
 "data":
  [
    {
      "customfield_id": "1",
      "customfielditem_id": "1",
      "applies_to": "jobcodes",
      "applies_to_id": "1",
      "active": true
    },
    {
      "customfield_id": "1",
      "customfielditem_id": "1",
      "applies_to": "invalid-applies-to",
      "applies_to_id": "2",
      "active": true
    }
  ]
}

Request

curl -X POST \
  https://rest.tsheets.com/api/v1/customfielditemfilters \
  -H 'Authorization: Bearer <TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '<REQUEST BODY>'
var client = new RestClient("https://rest.tsheets.com/api/v1/customfielditemfilters");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <TOKEN>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "<REQUEST BODY>", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/customfielditemfilters")
Dim request = New RestRequest(Method.POST)
request.AddHeader("Authorization", "Bearer <TOKEN>")
request.AddHeader("Content-Type", "application/json")
request.AddParameter("application/json", "<REQUEST BODY>", ParameterType.RequestBody);
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<REQUEST BODY>");
Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/customfielditemfilters")
  .post(body)
  .addHeader("Authorization", "Bearer <TOKEN>")
  .addHeader("Content-Type", "application/json")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/customfielditem_filters?modified_since=2018-07-17T00:00:00-00:00",
  "method": "POST",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
    "Content-Type", "application/json",
  },
  "processData": false,
  "data": "<REQUEST BODY>"
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'POST',
  url: 'https://rest.tsheets.com/api/v1/customfielditemfilters',
  headers: 
  { 
     'Authorization': 'Bearer <TOKEN>',
     'Content-Type': 'application/json',
  },
  body: '<REQUEST BODY>',
  json: true };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/customfielditemfilters');
$request->setMethod(HTTP_METH_POST);

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
  'Content-Type' => 'application/json',
));

$request->setBody('<REQUEST BODY>');

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/customfielditemfilters")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <TOKEN>',
request["Content-Type"] = 'application/json',
request.body = "<REQUEST BODY>"

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/customfielditemfilters"

payload = "<REQUEST BODY>"
headers = {
    'Authorization': 'Bearer <TOKEN>',
    'Content-Type': 'application/json',
    }

response = requests.request("POST", url, data=payload, headers=headers)

print(response.text)
package main

import (
  "fmt"
  "strings"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/customfielditemfilters"

  payload := strings.NewReader("<REQUEST BODY>")

  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, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))

}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
   "Content-Type": "application/json",
]
let parameters = <REQUEST BODY> as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/customfielditemfilters")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest,
  completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');
$client->addHeader('Content-Type', 'application/json');

$req = '<REQUEST BODY>';

$url="https://rest.tsheets.com/api/v1/customfielditemfilters"; 

$client->POST($url, $req);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "customfielditems": {
      "1": {
        "_status_code": 200,
        "_status_message": "Created",
        "id": 101,
        "customfield_id": 1,
        "customfielditem_id": 1,
        "applies_to": "jobcodes",
        "applies_to_id": 1
        "active": true
      },
      "2": {
        "_status_code": 417,
        "_status_message": "Expectation Failed",
        "_status_extra": "The applies_to value must be one of the following: jobcodes, users, groups.",
        "customfield_id": "1",
        "customfielditem_id": "1",
        "applies_to": "invalid-applies-to",
        "applies_to_id": "2",
        "active": true
      }
    }
  },
  "supplemental_data": {
    "jobcodes": {...},
    "customfields": {...},
    "customfielditems": {...}
  }
}

Add one or more customfielditemfilters.

HTTP Request

posthttps://rest.tsheets.com/api/v1/customfielditem_filters

Properties

Pass an array of customfielditemfilter objects as the value to a 'data' property (see example).

customfield_id
required
Int The id of the customfield this filter to belong to.
customfielditem_id
required
Int The id of the customfielditem this filter to belong to.
applies_to
read-write
String Entity type this filter relates to. Together with applies_to_id, determines what this filtered item relates to. The possible values are: 'jobcodes', 'users', or 'groups'. For example: If this value was 'jobcodes' then the applies_to_id value would indicate which jobcode this filter referred to. If requested, the supplemental data will also contain this jobcode.
applies_to_id
read-write
Int The jobcode, user, or group that this filter relates to. Together with applies_to, determines what this filtered item relates to. For example: If the value of the applies_to field was 'jobcodes' this value would indicate which jobcode this filter referred to. If requested, the supplemental data will also contain this jobcode.
active
read-write
Boolean true or false. If false, this customfielditem_filter is considered archived or deleted.

For a full list of the properties that may be set on a customfielditemfilter, see The Item Filter Object.

Status Codes

Each customfielditemfilter that is created will come back with a _status_code and _status_message that will indicate whether the customfielditemfilter was created successfully. If there was a problem creating a customfielditemfilter, there may also be an additional field, _status_extra, which will contain more details about the failure.

200 OK. customfielditemfilter was created successfully.
417 Expectation Failed. Something was wrong or missing with the properties supplied for this customfielditemfilter. See the _status_extra value for more detail.

Update Item Filters

Example: Update two customfielditemfilters. One succeeds. The other fails because of an invalid applies_to.

Request Body

{
 "data":
  [
    {
      "id": 101,
      "active": "no"
    },
    {
      "id": 102,
      "applies_to": "invalid-applies-to"
    }
  ]
}

Request

curl -X POST \
  https://rest.tsheets.com/api/v1/customfielditemfilters \
  -H 'Authorization: Bearer <TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '<REQUEST BODY>'
var client = new RestClient("https://rest.tsheets.com/api/v1/customfielditemfilters");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <TOKEN>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "<REQUEST BODY>", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/customfielditemfilters")
Dim request = New RestRequest(Method.POST)
request.AddHeader("Authorization", "Bearer <TOKEN>")
request.AddHeader("Content-Type", "application/json")
request.AddParameter("application/json", "<REQUEST BODY>", ParameterType.RequestBody);
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<REQUEST BODY>");
Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/customfielditemfilters")
  .post(body)
  .addHeader("Authorization", "Bearer <TOKEN>")
  .addHeader("Content-Type", "application/json")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/customfielditem_filters?modified_since=2018-07-17T00:00:00-00:00",
  "method": "POST",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
    "Content-Type", "application/json",
  },
  "processData": false,
  "data": "<REQUEST BODY>"
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'POST',
  url: 'https://rest.tsheets.com/api/v1/customfielditemfilters',
  headers: 
  { 
     'Authorization': 'Bearer <TOKEN>',
     'Content-Type': 'application/json',
  },
  body: '<REQUEST BODY>',
  json: true };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/customfielditemfilters');
$request->setMethod(HTTP_METH_POST);

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
  'Content-Type' => 'application/json',
));

$request->setBody('<REQUEST BODY>');

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/customfielditemfilters")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <TOKEN>',
request["Content-Type"] = 'application/json',
request.body = "<REQUEST BODY>"

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/customfielditemfilters"

payload = "<REQUEST BODY>"
headers = {
    'Authorization': 'Bearer <TOKEN>',
    'Content-Type': 'application/json',
    }

response = requests.request("POST", url, data=payload, headers=headers)

print(response.text)
package main

import (
  "fmt"
  "strings"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/customfielditemfilters"

  payload := strings.NewReader("<REQUEST BODY>")

  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, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))

}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
   "Content-Type": "application/json",
]
let parameters = <REQUEST BODY> as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/customfielditemfilters")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest,
  completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');
$client->addHeader('Content-Type', 'application/json');

$req = '<REQUEST BODY>';

$url="https://rest.tsheets.com/api/v1/customfielditemfilters"; 

$client->POST($url, $req);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "customfielditems": {
      "1": {
        "id": 101,
        "customfield_id": 2,
        "customfielditem_id": 3,
        "applies_to": "jobcodes",
        "applies_to_id": 1
        "active": true,
        "last_modified": "2022-02-24T21:45:19+00:00",
        "_status_code": 200,
        "_status_message": "Updated",
      },
      "2": {
        "id": 102,
        "applies_to": "invalid_applies_to",
        "_status_code": 417,
        "_status_message": "Expectation Failed",
        "_status_extra": "The applies_to value must be one of the following: jobcodes, users, groups."
      }
    }
  },
  "supplemental_data": {
    "jobcodes": {...},
    "customfields": {...},
    "customfielditems": {...}
  }
}

Edit one or more customfielditemfilters.

HTTP Request

puthttps://rest.tsheets.com/api/v1/customfielditem_filters

Properties

Pass an array of customfielditemfilter objects as the value to a 'data' property (see example).

id
required
Int Id of the customfielditemfilter.

All other read-write properties defined on an Item Filter object may be passed in to the request with a new value in order to change it. If the value passed in is the same as it was previously, or if a particular property is not passed in at all, it will be ignored.

Status Codes

Each customfielditemfilter that is created will come back with a _status_code and _status_message that will indicate whether the customfielditemfilter was created successfully. If there was a problem creating a customfielditemfilter, there may also be an additional field, _status_extra, which will contain more details about the failure.

200 OK. customfielditemfilter was created successfully.
417 Expectation Failed. Something was wrong or missing with the properties supplied for this customfielditemfilter. See the _status_extra value for more detail.

Custom Field Item Jobcode Filters

The Jobcode Filter Object

Example

{
  "id": 3429889,
  "last_modified": "2018-07-17T23:40:51+00:00",
  "filtered_customfielditems": {
    "266131": [
      "541863",
      "541869"
    ],
    "266129": [ ]
  }
}

Following is a list of the properties that belong to a customfielditem_jobcode_filter object, and a description of each.

id
read-only
Int Id of the jobcode to which the filters belong.
last_modified
read-only
String The latest date/time when one of the filtered items was updated, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm).
filtered_customfielditems
read-write
Map Each entity represents a custom field's active filters where the key is the custom field id and the value is an array of item ids to which the jobcode is assigned.

Retrieve Jobcode Filters

Example: Retrieve a list of all customfielditem_jobcode_filters modified since a given date/time.

Request

curl "https://rest.tsheets.com/api/v1/customfielditem_jobcode_filters?modified_since=2018-07-17T00:00:00-00:00" \
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/customfielditem_jobcode_filters?modified_since=2018-07-17T00:00:00-00:00");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/customfielditem_jobcode_filters?modified_since=2018-07-17T00:00:00-00:00")
Dim request = New RestRequest(Method.[GET])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/customfielditem_jobcode_filters?modified_since=2018-07-17T00:00:00-00:00")
  .get()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/customfielditem_jobcode_filters?modified_since=2018-07-17T00:00:00-00:00",
  "method": "GET",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'GET',
  url: 'https://rest.tsheets.com/api/v1/customfielditem_jobcode_filters',
  qs: {
    modified_since: '2018-07-17T00:00:00-00:00',
  },
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/customfielditem_jobcode_filters');
$request->setMethod(HTTP_METH_GET);

$request->setQueryData(array(
  'modified_since' => '2018-07-17T00:00:00-00:00',
));

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/customfielditem_jobcode_filters?modified_since=2018-07-17T00:00:00-00:00")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/customfielditem_jobcode_filters"

querystring = {
  "modified_since":"2018-07-17T00:00:00-00:00",
}

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/customfielditem_jobcode_filters?modified_since=2018-07-17T00:00:00-00:00"

  req, _ := http.NewRequest("GET", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/customfielditem_jobcode_filters?modified_since=2018-07-17T00:00:00-00:00")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest, completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/customfielditem_jobcode_filters?modified_since=2018-07-17T00:00:00-00:00"; 

$client->GET($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "customfielditem_jobcode_filters": {
      "3429889": {
        "id": 3429889,
        "last_modified": "2018-07-17T23:40:51+00:00",
        "filtered_customfielditems": {
          "266131": [
            "541863",
            "541869"
          ],
          "266129": [ ]
        }
      },
      "3429509": {
        "id": 3429509,
        "last_modified": "2018-08-10T11:09:12+00:00",
        "filtered_customfielditems": {
          "266129": [
            "541892",
            "541899"
          ]
        }
      }
    }
  },
  "more": false
}

Retrieves a list of all customfielditem filters associated with a jobcode with options to narrow down the results.

Custom field item filters are used to limit the choices that should be made available for selecting customfielditems for a particular customfield based on a jobcode. If filtered items exist for a given jobcode the choices for the indicated customfield should be limited to those customfielditems only.

HTTP Request

gethttps://rest.tsheets.com/api/v1/customfielditem_jobcode_filters

Filter Parameters

jobcode_ids
optional
Int Comma separated list of one or more jobcode ids you'd like to filter on.
modified_before
optional
String Only customfielditem filters modified before this date/time will be returned, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm).
modified_since
optional
String Only customfielditem filters modified since this date/time will be returned, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm).
per_page
optional
Int Deprecated. Use limit for new code.
Represents how many results you'd like to retrieve per request. Default is 50. Max is 50.
If a value over 50 is provided, it is ignored, and the max is used.
limit
optional
Int Represents how many results you'd like to retrieve per request. Default is 200. Max is 200.
If present, this value must be: an integer, greater than zero, and not greater than 200.
Setting limit less than 1 or greater than 200 will result in an error.
page
optional
Int Represents the page of results you'd like to retrieve. Default is 1.

Custom Field Item User Filters

The User Filter Object

Example

{
  "id": 2064699,
  "type": "user",
  "last_modified": "2018-07-17T23:40:51+00:00",
  "filtered_customfielditems": {
    "272563": [
      "1884205",
      "1884207",
      "1884212"
    ],
    "272565": [ ]
  }
}

Following is a list of the properties that belong to a customfielditem_user_filter object, and a description of each.

id
read-only
Int Id of the user or group to which the filters belong.
type
read-write
String The entities filter type: 'user' or 'group'.
last_modified
read-only
String The latest date/time when one of the filtered items was updated, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm).
filtered_customfielditems
read-write
Map Each entity represents a custom field's active filters where the key is the custom field id and the value is an array of item ids to which the user is assigned.

Retrieve User Filters

Example: Retrieve a list of all customfielditem_user_filters modified since a given date/time.

Request

curl "https://rest.tsheets.com/api/v1/customfielditem_user_filters?modified_since=2018-07-17T00:00:00-00:00" \
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/customfielditem_user_filters?modified_since=2018-07-17T00:00:00-00:00");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/customfielditem_user_filters?modified_since=2018-07-17T00:00:00-00:00")
Dim request = New RestRequest(Method.[GET])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/customfielditem_user_filters?modified_since=2018-07-17T00:00:00-00:00")
  .get()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/customfielditem_user_filters?modified_since=2018-07-17T00:00:00-00:00",
  "method": "GET",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'GET',
  url: 'https://rest.tsheets.com/api/v1/customfielditem_user_filters',
  qs: {
    modified_since: '2018-07-17T00:00:00-00:00',
  },
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/customfielditem_user_filters');
$request->setMethod(HTTP_METH_GET);

$request->setQueryData(array(
  'modified_since' => '2018-07-17T00:00:00-00:00',
));

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/customfielditem_user_filters?modified_since=2018-07-17T00:00:00-00:00")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/customfielditem_user_filters"

querystring = {
  "modified_since":"2018-07-17T00:00:00-00:00",
}

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/customfielditem_user_filters?modified_since=2018-07-17T00:00:00-00:00"

  req, _ := http.NewRequest("GET", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/customfielditem_user_filters?modified_since=2018-07-17T00:00:00-00:00")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest, completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/customfielditem_user_filters?modified_since=2018-07-17T00:00:00-00:00"; 

$client->GET($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "customfielditem_user_filters": {
      "2064699": {
        "id": 2064699,
        "type": "user",
        "last_modified": "2018-07-17T23:40:51+00:00",
        "filtered_customfielditems": {
          "272563": [
            "1884205",
            "1884207",
            "1884212"
          ],
          "272565": [

          ]
        }
      },
      "2064699": {
        "id": 2064699,
        "type": "group",
        "last_modified": "2018-07-21T11:12:34+00:00",
        "filtered_customfielditems": {
          "272563": [
            "1884206",
            "1884209"
          ]
        }
      },
      "2064796": {
        "id": 2064796,
        "type": "user",
        "last_modified": "2018-08-10T11:09:12+00:00",
        "filtered_customfielditems": {
          "272563": [
            "1884206",
            "1884208"
          ]
        }
      }
    }
  },
  "more": false
}

Retrieves a list of all customfielditem filters associated with a user or group with options to narrow down the results.

Custom field item filters are used to limit the choices that should be made available for selecting customfielditems for a particular customfield based on a user. If filtered items exist for a given user or user's group the choices for the indicated customfield should be limited to those customfielditems only.

Please note that users can belong to groups and that groups can have filtered items. When requesting filtered items for a user, you can pass the 'include_user_group' option to return the customfielditem_user_filters for both the user and their assigned group.

HTTP Request

gethttps://rest.tsheets.com/api/v1/customfielditem_user_filters

Filter Parameters

user_id
optional
Int Limits the returned filters to only those for the specified user_id. You can also include items for this user's group automatically if you include the include_user_group parameter.
group_id
optional
Int Limits the returned filters to only those for the specified group_id.
include_user_group
optional
Boolean true or false. If a user_id is supplied, will return filters for that user's group as well.
modified_before
optional
String Only customfielditem filters modified before this date/time will be returned, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm).
modified_since
optional
String Only customfielditem filters modified since this date/time will be returned, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm).
per_page
optional
Int Deprecated. Use limit for new code.
Represents how many results you'd like to retrieve per request. Default is 50. Max is 50.
If a value over 50 is provided, it is ignored, and the max is used.
limit
optional
Int Represents how many results you'd like to retrieve per request. Default is 200. Max is 200.
If present, this value must be: an integer, greater than zero, and not greater than 200.
Setting limit less than 1 or greater than 200 will result in an error.
page
optional
Int Represents the page of results you'd like to retrieve. Default is 1.

Effective Settings

The Effective Settings Object

Example

{
  "general": {
    "settings": {
      "calculate_overtime": "1",
      "clockout_override": 1,
      "clockout_override_hours": 10,
      "clockout_override_notify_admin": 1,
      "clockout_override_notify_mgrs": 0,
      "daily_doubletime": "0",
      "daily_overtime": "0",
      "daily_regular_hours": 8,
      "date_locale": "us",
      "emp_panel": 1,
      "emp_panel_email": "0",
      "emp_panel_passwd": "0",
      "emp_panel_tz": "0",
      "employee_pto_entry": 0,
      "enable_timesheet_notes": "1",
      "hide_working_time": "0",
      "jc_label": "Job",
      "lunch_deduct": 0,
      "lunch_length": 1,
      "lunch_threshold": 9,
      "max_customfielditems": "-1",
      "max_jobcodes": "-1",
      "parent_clockin_display": 0,
      "payroll_end_date": "2018-09-28",
      "payroll_first_end_day": "1",
      "payroll_last_end_day": "16",
      "payroll_month_end_day": "1",
      "payroll_type": "biweekly",
      "pto_entry": 1,
      "pto_overtime": 0,
      "simple_clockin": 0,
      "time_format": 12,
      "timecard_fields": "JOBCODE,134913,143369,143377",
      "timeclock_label": "Time Clock",
      "timesheet_edit_notes_for_all_users": 0,
      "timesheet_notes_notify_admin": 0,
      "timesheet_notes_notify_mgrs": 0,
      "timesheet_notes_required": 0,
      "tz": "America/Denver",
      "week_start": 0,
      "weekly_regular_hours": "40"
    },
    "last_modified": "2019-02-11T17:45:18+00:00"
  },
  "alerts": {
    "settings": {
      "installed": 0
    },
    "last_modified": "2001-01-01T12:00:00+00:00"
  },
  "approvals": {
    "settings": {
      "installed": "1"
    },
    "last_modified": "2019-01-25T20:53:52+00:00"
  },
  "breaks": {
    "settings": {
      "hide_pre_clockout_option": 0
    },
    "last_modified": "2019-01-25T20:53:52+00:00"
  },
  "dcaa": {
    "settings": {
      "installed": 0
    },
    "last_modified": "2001-01-01T12:00:00+00:00"
  },
  "dialin": {
    "settings": {
      "installed": 0
    },
    "last_modified": "2001-01-01T12:00:00+00:00"
  },
  "files": {
    "settings": {
      "installed": "1",
      "files_addon_app_discovery_notification": "1"
    },
    "last_modified": "2019-01-25T20:53:52+00:00"
  },
  "invoicing": {
    "settings": {
      "installed": 0
    },
    "last_modified": "2001-01-01T12:00:00+00:00"
  },
  "location_aware": {
    "settings": {
      "installed": 1,
      "show_location": "1"
    },
    "last_modified": "2019-01-25T20:53:52+00:00"
  },
  "mobile_app_integrations": {
    "settings": {
      "installed": 1,
      "apps": {
        "expensify": {
          "triggers": {
            "TSMTriggerButton": {
              "id": 553,
              "active": true,
              "jobcode_ids": [
                0
              ],
              "android_playstore_uri": "org.me.mobiexpensifyg",
              "android_call_scheme": "http://mobile.expensify.com/SmartScan",
              "iphone_appstore_url": "https://itunes.apple.com/us/app/expensify-expense-reports/id471713959",
              "iphone_call_scheme": "http://mobile.expensify.com",
              "call_url_host": "SmartScan",
              "call_uri_format": "tag=%JOBCODE_NAME%&billable=%JOBCODE_BILLABLE%&email=%EMAIL%&callbackURL=%TSHEETS_RETURN_URL%",
              "callback_uri_format": ""
            }
          }
        }
      }
    },
    "last_modified": "2019-01-25T20:53:52+00:00"
  },
  "mobile_app_settings": {
    "settings": {
      "installed": "1",
      "location_tracking": "off",
      "mandatory_location_services": "0"
    },
    "last_modified": "2019-02-09T18:39:20+00:00"
  },
  "reminders": {
    "settings": {
      "installed": 1
    },
    "last_modified": "2019-01-25T20:53:52+00:00"
  },
  "projects": {
    "settings": {
      "installed": 0
    },
    "last_modified": "2001-01-01T12:00:00+00:00"
  },
  "quickbooks": {
    "settings": {
      "installed": "1",
      "connector": "qbia_online",
      "connector_type": "payroll_single_sku",
      "two_way_sync_enabled_for_user": 0
    },
    "last_modified": "2019-01-25T20:53:52+00:00"
  },
  "restapi": {
    "settings": {
      "installed": "1"
    },
    "last_modified": "2019-01-25T20:53:52+00:00"
  },
  "rounding": {
    "settings": {
      "installed": 0
    },
    "last_modified": "2001-01-01T12:00:00+00:00"
  },
  "schedule": {
    "settings": {
      "installed": "1",
      "business_hours_end": "17:00:00",
      "business_hours_start": "08:00:00",
      "drafted_first_schedule_event_occurred": "1",
      "manage_schedule_permission": "company",
      "published_first_schedule_event_occurred": "1",
      "trial_expiration_date": "2018-10-17",
      "view_schedule_permission": "company",
      "learning_step": "7",
      "employee_view": "company",
      "manager_view": "company"
    },
    "last_modified": "2019-02-09T18:03:55+00:00"
  },
  "sms": {
    "settings": {
      "installed": 0
    },
    "last_modified": "2001-01-01T12:00:00+00:00"
  },
  "sounds": {
    "settings": {
      "installed": 0
    },
    "last_modified": "2001-01-01T12:00:00+00:00"
  },
  "customfields": {
    "settings": {
      "maximum_allowed_timesheet_custom_fields": 6,
      "installed": "1"
    },
    "last_modified": "2019-02-10T20:34:10+00:00"
  },
  "time_entry": {
    "settings": {
      "installed": 1,
      "time_entry_method": "timecard",
      "mtc_format_time_display": "hhmm",
      "time_entry": 0,
      "timecard": 1,
      "weekly_timecard": 1,
      "timecard_daily": 0,
      "timesheet_edit": 0,
      "timesheet_map": 1,
      "pto_entry": 1,
      "timesheet_list_date_range_selection": "month",
      "timesheet_list_show_days_with_no_time": 0,
      "timesheet_list_wrap_text": 0,
      "timesheet_list_column_selection": "time,job,location,kiosk,attachments,notes",
      "timesheet_list_bottomless_scroll": 1,
      "mtc_combine_regular_timesheets": "0"
    },
    "last_modified": "2019-01-25T20:53:52+00:00"
  },
  "toodledo": {
    "settings": {
      "installed": 0
    },
    "last_modified": "2001-01-01T12:00:00+00:00"
  },
  "twitter": {
    "settings": {
      "installed": 0
    },
    "last_modified": "2001-01-01T12:00:00+00:00"
  },
  "xero": {
    "settings": {
      "installed": 0
    },
    "last_modified": "2001-01-01T12:00:00+00:00"
  },
  "zenpayroll": {
    "settings": {
      "installed": 0
    },
    "last_modified": "2001-01-01T12:00:00+00:00"
  }
}

All combined, cascaded settings that apply to a given user are contained in the effective settings object.

The effective settings object consists of a series of sections. Each section contains a settings and a last_modified property. The settings property is a list of key/value pairs. The last_modified property is an ISO 8601-formatted timestamp. It gets updated any time a key/value pair within a section has changed.

Below is a list of the possible section headings.

general General application settings
alerts Settings for the Alerts Add-On
approvals Settings for the Approvals Add-On
breaks Settings for the Breaks Add-On
dcaa Settings for the DCAA Compliance Add-On
dialin Settings for the Dial-in Add-On
files Settings for the Files Add-On
invoicing Settings for the Invoicing Add-On
location_aware Settings for the Location Aware Add-On
mobile_app_integrations Settings for the Mobile App Integrations Add-On
mobile_app_settings Settings for the Mobile App Settings Add-On
reminders Settings for the Reminders Add-On
projects Settings for the Projects Add-On
quickbooks Settings for the Quickbooks Integration Add-On
restapi Settings for the TSheets Rest API Add-On
rounding Settings for the Timesheet Rounding Add-On
schedule Settings for the Schedule Add-On
sms Settings for the Text Messaging Add-On
sounds Settings for the Sounds Add-On
customfields Settings for the Advanced Tracking Add-On
time_entry Settings for the Time Card Selector Add-On
toodledo Settings for the Toodledo Add-On
twitter Settings for the Twitter Add-On
xero Settings for the Xero Integration Add-On
zenpayroll Settings for the Zen Payroll Integration Add-On

Retrieve Effective Settings

Example: Retrieve a list of all effective settings for a specific user.

Request

curl "https://rest.tsheets.com/api/v1/effective_settings?user_id=1234" \
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/effective_settings?user_id=1234");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/effective_settings?user_id=1234")
Dim request = New RestRequest(Method.[GET])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/effective_settings?user_id=1234")
  .get()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/effective_settings?user_id=1234",
  "method": "GET",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'GET',
  url: 'https://rest.tsheets.com/api/v1/effective_settings',
  qs: {
    user_id: '1234',
  },
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/effective_settings');
$request->setMethod(HTTP_METH_GET);

$request->setQueryData(array(
  'user_id' => '1234',
));

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/effective_settings?user_id=1234")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/effective_settings"

querystring = {
  "user_id":"1234",
}

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/effective_settings?user_id=1234"

  req, _ := http.NewRequest("GET", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/effective_settings?user_id=1234")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest, completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/effective_settings?user_id=1234"; 

$client->GET($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Example: Retrieve a list of all effective settings modified since a specified date. Currently logged in user's id will be used since none is specified in the request.

Request

curl "https://rest.tsheets.com/api/v1/effective_settings?modified_since=2018-03-01T00:00:00-0600" \
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/effective_settings?modified_since=2018-03-01T00:00:00-0600");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/effective_settings?modified_since=2018-03-01T00:00:00-0600")
Dim request = New RestRequest(Method.[GET])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/effective_settings?modified_since=2018-03-01T00:00:00-0600")
  .get()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/effective_settings?modified_since=2018-03-01T00:00:00-0600",
  "method": "GET",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'GET',
  url: 'https://rest.tsheets.com/api/v1/effective_settings',
  qs: {
    modified_since: '2018-03-01T00:00:00-0600',
  },
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/effective_settings');
$request->setMethod(HTTP_METH_GET);

$request->setQueryData(array(
  'modified_since' => '2018-03-01T00:00:00-0600',
));

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/effective_settings?modified_since=2018-03-01T00:00:00-0600")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/effective_settings"

querystring = {
  "modified_since":"2018-03-01T00:00:00-0600",
}

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/effective_settings?modified_since=2018-03-01T00:00:00-0600"

  req, _ := http.NewRequest("GET", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/effective_settings?modified_since=2018-03-01T00:00:00-0600")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest, completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/effective_settings?modified_since=2018-03-01T00:00:00-0600"; 

$client->GET($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "effective_settings": {
      "general": {
        "settings": {
          "calculate_overtime": "1",
          "clockout_override": 1,
          "clockout_override_hours": 10,
          "clockout_override_notify_admin": 1,
          "clockout_override_notify_mgrs": 0,
          "daily_doubletime": "0",
          "daily_overtime": "0",
          "daily_regular_hours": 8,
          "date_locale": "us",
          "emp_panel": 1,
          "emp_panel_email": "0",
          "emp_panel_passwd": "0",
          "emp_panel_tz": "0",
          "employee_pto_entry": 0,
          "enable_timesheet_notes": "1",
          "hide_working_time": "0",
          "jc_label": "Job",
          "lunch_deduct": 0,
          "lunch_length": 1,
          "lunch_threshold": 9,
          "max_customfielditems": "-1",
          "max_jobcodes": "-1",
          "parent_clockin_display": 0,
          "payroll_end_date": "2018-09-28",
          "payroll_first_end_day": "1",
          "payroll_last_end_day": "16",
          "payroll_month_end_day": "1",
          "payroll_type": "biweekly",
          "pto_entry": 1,
          "pto_overtime": 0,
          "simple_clockin": 0,
          "time_format": 12,
          "timecard_fields": "JOBCODE,134913,143369,143377",
          "timeclock_label": "Time Clock",
          "timesheet_edit_notes_for_all_users": 0,
          "timesheet_notes_notify_admin": 0,
          "timesheet_notes_notify_mgrs": 0,
          "timesheet_notes_required": 0,
          "tz": "America/Denver",
          "week_start": 0,
          "weekly_regular_hours": "40"
        }
        "last_modified": "2018-04-05T19:19:45+00:00"
      },
      "alerts": {
        "settings": {
          "installed": 0
        },
        "last_modified": "2001-01-01T12:00:00+00:00"
      },
      "approvals": {
        "settings": {
          "installed": "1"
        },
        "last_modified": "2018-04-04T19:42:03+00:00"
      },
      "breaks": {
        "settings": {
          "hide_pre_clockout_option": 0
        },
        "last_modified": "2018-04-04T19:42:03+00:00"
      },
      "dcaa": {
        "settings": {
          "installed": 0
        },
        "last_modified": "2001-01-01T12:00:00+00:00"
      },
      "dialin": {
        "settings": {
          "installed": 0
        },
        "last_modified": "2001-01-01T12:00:00+00:00"
      },
      "files": {
        "settings": {
          "installed": 0
        },
        "last_modified": "2001-01-01T12:00:00+00:00"
      },
      "invoicing": {
        "settings": {
          "installed": 0
        },
        "last_modified": "2001-01-01T12:00:00+00:00"
      },
      "mobile_app_integrations": {
        "settings": {
          "installed": 0,
          "apps": ""
        },
        "last_modified": "2001-01-01T12:00:00+00:00"
      },
      "mobile_app_settings": {
        "settings": {
          "installed": 1,
          "location_tracking": "optional",
          "mandatory_location_services": 0
        },
        "last_modified": "2018-04-04T19:42:03+00:00"
      },
      "reminders": {
        "settings": {
          "installed": 1
        },
        "last_modified": "2018-04-04T19:42:03+00:00"
      },
      "quickbooks": {
        "settings": {
          "installed": "1",
          "connector": "qbia_online",
          "two_way_sync_enabled_for_user": 0
        },
        "last_modified": "2018-04-04T19:42:03+00:00"
      },
      "restapi": {
        "settings": {
          "installed": 0
        },
        "last_modified": "2001-01-01T12:00:00+00:00"
      },
      "rounding": {
        "settings": {
          "installed": 0
        },
        "last_modified": "2001-01-01T12:00:00+00:00"
      },
      "schedule": {
        "settings": {
          "installed": "1",
          "business_hours_end": "17:00:00",
          "business_hours_start": "08:00:00",
          "manage_schedule_permission": "company",
          "trial_expiration_date": "2018-04-11",
          "view_schedule_permission": "company",
          "employee_view": "company",
          "manager_view": "company"
        },
        "last_modified": "2018-04-04T19:42:03+00:00"
      },
      "sms": {
        "settings": {
          "installed": 0,
          "email_notify": "1",
          "mobile_number": "2087231456",
          "sms_notify": "1"
        },
        "last_modified": "2018-03-27T16:13:35+00:00"
      },
      "sounds": {
        "settings": {
          "installed": 0
        },
        "last_modified": "2001-01-01T12:00:00+00:00"
      },
      "customfields": {
        "settings": {
          "maximum_allowed_timesheet_custom_fields": 6,
          "installed": "1"
        },
        "last_modified": "2018-04-04T19:42:03+00:00"
      },
      "time_entry": {
        "settings": {
          "installed": 1,
          "time_entry_method": "timecard",
          "mtc_format_time_display": "hhmm",
          "time_entry": 0,
          "timecard": 1,
          "weekly_timecard": 1,
          "timecard_daily": 0,
          "timesheet_edit": 0,
          "timesheet_map": 1,
          "pto_entry": 1,
          "timesheet_list_date_range_selection": "week",
          "timesheet_list_show_days_with_no_time": 1,
          "timesheet_list_wrap_text": 0,
          "timesheet_list_column_selection": "time,job,location,kiosk,attachments,notes",
          "timesheet_list_bottomless_scroll": 0
        },
        "last_modified": "2018-04-04T19:42:03+00:00"
      },
      "toodledo": {
        "settings": {
          "installed": 0
        },
        "last_modified": "2001-01-01T12:00:00+00:00"
      },
      "twitter": {
        "settings": {
          "installed": 0
        },
        "last_modified": "2001-01-01T12:00:00+00:00"
      },
      "xero": {
        "settings": {
          "installed": 0
        },
        "last_modified": "2001-01-01T12:00:00+00:00"
      },
      "zenpayroll": {
        "settings": {
          "installed": 0
        },
        "last_modified": "2001-01-01T12:00:00+00:00"
      }
    }
  }
}

Retrieves a list of all effective settings associated with a single user, with optional filters to narrow down the results.

HTTP Request

gethttps://rest.tsheets.com/api/v1/effective_settings

Filter Parameters

user_id
optional
Int User id for whom you'd like to retrieve effective settings. If none is specified, the currently logged in user's id will be used. Only effective settings that apply to this user_id will be returned. An admin will see more settings than a regular user will.
modified_before
optional
String Only sections with settings modified before this date/time will be returned, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm).
modified_since
optional
String Only sections with settings modified since this date/time will be returned, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm).

Estimate Items

The Estimate Item Object

Example

{
    "id": 596193,
    "estimated_seconds": 46800,
    "estimate_id": 841513,
    "active": true,
    "created": "2019-09-11T16:24:14+00:00",
    "last_modified": "2019-09-11T16:24:14+00:00",
    "type": "tag_clouds",
    "type_id": 8680081
}

Following is a list of the properties that belong to an estimate item object, and a description of each.

id
read-only
Int ID of this estimate item.
estimated_seconds
read-write
Int The estimated number of seconds.
estimate_id
write-once
Int The estimate this estimate item belongs to.
active
read-write
Boolean True or false. If false, this estimate is considered deleted.
created
read
String Date/time when this estimate was created, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm).
last_modified
read
String Date/time when this estimate was last modified, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm).
type
read-write
String The estimate item type. One of 'none' or 'tag_clouds'. NOTE: A type of 'tag_clouds' should be 'customfields' instead. This will be corrected soon.
type_id
read-write
Int The customfielditem id if type is 'tag_clouds'.

Retrieve Estimate Items

Example: Retrieve a list of estimates based on the provided filter.

Request

curl "https://rest.tsheets.com/api/v1/estimate_items" \
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/estimate_items");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/estimate_items")
Dim request = New RestRequest(Method.[GET])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/estimate_items")
  .get()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/estimate_items",
  "method": "GET",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'GET',
  url: 'https://rest.tsheets.com/api/v1/estimate_items',
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/estimate_items');
$request->setMethod(HTTP_METH_GET);

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/estimate_items")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/estimate_items"

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/estimate_items"

  req, _ := http.NewRequest("GET", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/estimate_items")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest, completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/estimate_items"; 

$client->GET($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
    "results": {
        "estimate_items": {
            "596275": {
                "id": 596275,
                "estimated_seconds": 46800,
                "estimate_id": 841513,
                "active": true,
                "created": "2019-09-11T16:39:23+00:00",
                "last_modified": "2019-09-11T16:39:23+00:00",
                "type": "tag_clouds",
                "type_id": 8681617
            },
            "596276": {
                "id": 596275,
                "estimated_seconds": 60000,
                "estimate_id": 841513,
                "active": true,
                "created": "2019-09-12T16:00:00+00:00",
                "last_modified": "2019-09-13T15:32:21+00:00",
                "type": "tag_clouds",
                "type_id": 8681617
            }
        }
    },
    "supplemental_data": {
        "estimates": {
            "841513": {
                "id": 841513,
                "project_id": 1301813,
                "active": true,
                "created": "2019-09-11T16:24:14+00:00",
                "last_modified": "2019-09-11T16:24:14+00:00",
                "estimate_by": "customfields",
                "estimate_by__id": 1247597
            }
        }
    },
    "more": false
}

Retrieves a list of all estimate items associated with your company, with optional filters to narrow down the results.

HTTP Request

gethttps://rest.tsheets.com/api/v1/estimate_items

Filter Parameters

ids
optional
Int Comma-separated list of estimate item ids.
estimate_ids
optional
Int Comma-separated list of estimate ids associated with an estimate item.
active
optional
String 'yes', 'no', or 'both'. Default is 'yes'.
modified_before
optional
String Only estimate items modified before this date/time will be returned, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm)
modified_since
optional
String Only estimate items modified since this date/time will be returned, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm)
supplemental_data
optional
Boolean 'yes' or 'no'. Default is 'yes'. Indicates whether supplemental data should be returned.
per_page
optional
Int Deprecated. Use limit for new code.
Represents how many results you'd like to retrieve per request. Default is 50. Max is 50.
If a value over 50 is provided, it is ignored, and the max is used.
limit
optional
Int Represents how many results you'd like to retrieve per request. Default is 200. Max is 200.
If present, this value must be: an integer, greater than zero, and not greater than 200.
Setting limit less than 1 or greater than 200 will result in an error.
page
optional
Int Represents the page of results you'd like to retrieve.

Create Estimate Items

Example: Create a new estimate item.

Request Body

{
    "data": [{
        "estimated_seconds": 46800,
        "estimate_id": 841513,
        "active": true,
        "type": "tag_clouds",
        "type_id": 8681617
    }]
}

Request

curl -X POST \
  https://rest.tsheets.com/api/v1/estimate_items \
  -H 'Authorization: Bearer <TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '<REQUEST BODY>'
var client = new RestClient("https://rest.tsheets.com/api/v1/estimate_items");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <TOKEN>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "<REQUEST BODY>", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/estimate_items")
Dim request = New RestRequest(Method.POST)
request.AddHeader("Authorization", "Bearer <TOKEN>")
request.AddHeader("Content-Type", "application/json")
request.AddParameter("application/json", "<REQUEST BODY>", ParameterType.RequestBody);
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<REQUEST BODY>");
Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/estimate_items")
  .post(body)
  .addHeader("Authorization", "Bearer <TOKEN>")
  .addHeader("Content-Type", "application/json")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/estimate_items",
  "method": "POST",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
    "Content-Type", "application/json",
  },
  "processData": false,
  "data": "<REQUEST BODY>"
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'POST',
  url: 'https://rest.tsheets.com/api/v1/estimate_items',
  headers: 
  { 
     'Authorization': 'Bearer <TOKEN>',
     'Content-Type': 'application/json',
  },
  body: '<REQUEST BODY>',
  json: true };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/estimate_items');
$request->setMethod(HTTP_METH_POST);

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
  'Content-Type' => 'application/json',
));

$request->setBody('<REQUEST BODY>');

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/estimate_items")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <TOKEN>',
request["Content-Type"] = 'application/json',
request.body = "<REQUEST BODY>"

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/estimate_items"

payload = "<REQUEST BODY>"
headers = {
    'Authorization': 'Bearer <TOKEN>',
    'Content-Type': 'application/json',
    }

response = requests.request("POST", url, data=payload, headers=headers)

print(response.text)
package main

import (
  "fmt"
  "strings"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/estimate_items"

  payload := strings.NewReader("<REQUEST BODY>")

  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, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))

}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
   "Content-Type": "application/json",
]
let parameters = <REQUEST BODY> as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/estimate_items")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest,
  completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');
$client->addHeader('Content-Type', 'application/json');

$req = '<REQUEST BODY>';

$url="https://rest.tsheets.com/api/v1/estimate_items"; 

$client->POST($url, $req);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
    "results": {
        "estimate_items": {
            "1": {
                "_status_code": 200,
                "_status_message": "Created",
                "id": 596275,
                "estimated_seconds": 46800,
                "estimate_id": 841513,
                "active": true,
                "created": "2019-09-11T16:39:23+00:00",
                "last_modified": "2019-09-11T16:39:23+00:00",
                "type": "tag_clouds",
                "type_id": 8681617
            }
        }
    },
    "supplemental_data": {
        "estimates": {
            "841513": {
                "id": 841513,
                "project_id": 1301813,
                "active": true,
                "created": "2019-09-11T16:24:14+00:00",
                "last_modified": "2019-09-11T16:24:14+00:00",
                "estimate_by": "customfields",
                "estimate_by__id": 1247597
            }
        }
    }
}

Add one or more estimate items to your company.

HTTP Request

posthttps://rest.tsheets.com/api/v1/estimate_items

Properties

Pass an array of estimate item objects as the value to a 'data' property (see example).

estimate_id
required
Int The estimate this estimate item belongs to.
type
required
String The estimate type. One of 'none' or 'tag_clouds'.
type_id
optional
Int The customfielditem id if type is 'tag_clouds'.
estimated_seconds
optional
Int The estimated number of seconds.

For a full list of properties that may be set on an estimate item, see The Estimate Item Object.

Status Codes

Each estimate item that is created will come back with a _status_code and _status_message that will indicate whether the estimate item was created successfully. If there was a problem creating an estimate item, there may also be an additional field, _status_extra, which will contain more details about the failure.

200 OK. Estimate Item was created successfully.
417 Expectation Failed. Something was wrong or missing with the properties supplied for this estimate item. See the _status_extra value for more detail.

Update Estimate Items

Example: Edit an estimate item.

Request Body

{
  "data": [{
    "id": 596275,
    "type": "none",
    "type_id": 0
  }]
}

Request

curl -X PUT \
  https://rest.tsheets.com/api/v1/estimate_items \
  -H 'Authorization: Bearer <TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '<REQUEST BODY>'
var client = new RestClient("https://rest.tsheets.com/api/v1/estimate_items");
var request = new RestRequest(Method.PUT);
request.AddHeader("Authorization", "Bearer <TOKEN>");
request.AddHeader("Content-Type", "application/json");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/estimate_items")
Dim request = New RestRequest(Method.PUT)
request.AddHeader("Authorization", "Bearer <TOKEN>")
request.AddHeader("Content-Type", "application/json")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<REQUEST BODY>");
Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/estimate_items")
  .put(body)
  .addHeader("Authorization", "Bearer <TOKEN>")
  .addHeader("Content-Type", "application/json")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/estimate_items",
  "method": "PUT",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
    "Content-Type", "application/json",
  },
  "processData": false,
  "data": "<REQUEST BODY>"
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'PUT',
  url: 'https://rest.tsheets.com/api/v1/estimate_items',
  headers: 
  { 
     'Authorization': 'Bearer <TOKEN>',
     'Content-Type': 'application/json',
  },
  body: '<REQUEST BODY>',
  json: true };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/estimate_items');
$request->setMethod(HTTP_METH_PUT);

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
  'Content-Type' => 'application/json',
));

$request->setBody('<REQUEST BODY>');

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/estimate_items")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <TOKEN>',
request["Content-Type"] = 'application/json',
request.body = "<REQUEST BODY>"

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/estimate_items"

payload = "<REQUEST BODY>"
headers = {
    'Authorization': 'Bearer <TOKEN>',
    'Content-Type': 'application/json',
    }

response = requests.request("PUT", url, data=payload, headers=headers)

print(response.text)
package main

import (
  "fmt"
  "strings"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/estimate_items"

  payload := strings.NewReader("<REQUEST BODY>")

  req, _ := http.NewRequest("PUT", 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, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))

}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
   "Content-Type": "application/json",
]
let parameters = <REQUEST BODY> as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(
  url: NSURL(string: "http://rest.tsheets.com/api/v1/estimate_items")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "PUT"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest,
  completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');
$client->addHeader('Content-Type', 'application/json');

$req = '<REQUEST BODY>';

$url="http://rest.tsheets.com/api/v1/estimate_items"; 

$client->PUT($url, $req);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
    "results": {
        "estimate_items": {
            "1": {
                "_status_code": 200,
                "_status_message": "Updated",
                "id": 596275,
                "estimated_seconds": 46800,
                "estimate_id": 841513,
                "active": true,
                "created": "2019-09-11T16:39:23+00:00",
                "last_modified": "2019-09-11T17:06:38+00:00",
                "type": "tag_clouds",
                "type_id": 1247597
            }
        }
    },
    "supplemental_data": {
        "estimates": {
            "841513": {
                "id": 841513,
                "project_id": 1301813,
                "active": true,
                "created": "2019-09-11T16:24:14+00:00",
                "last_modified": "2019-09-11T16:24:14+00:00",
                "estimate_by": "customfields",
                "estimate_by__id": 1247597
            }
        }
    }
}

Edit one or more estimate items in your company.

HTTP Request

puthttps://rest.tsheets.com/api/v1/estimate_items

Properties

Pass an array of estimate item objects as the value to a 'data' property (see example).

id
required
Int Id of the estimate item.
type
optional
String The estimate type. One of 'none' or 'tag_clouds'.
type_id
optional
Int The customfielditem id if type is 'tag_clouds'.
estimated_seconds
optional
Int The estimated number of seconds.

Status Codes

Each estimate item that is edited will come back with a _status_code and _status_message that will indicate whether the estimate item was edited successfully. If there was a problem editing an estimate item, there may also be an additional field, _status_extra, which will contain more details about the failure.

200 OK. Estimate item was edited successfully.
417 Expectation Failed. Something was wrong or missing with the properties supplied for this estimate item. See the _status_extra value for more detail.

Estimates

The Estimate Object

Example

{
    "id": 840843,
    "project_id": 1301299,
    "active": true,
    "created": "2019-09-11T15:21:57+00:00",
    "last_modified": "2019-09-11T15:21:57+00:00",
    "estimate_by": "customfields",
    "estimate_by__id": 1247597
}

An estimate is associated with a project and is used to estimate the time needed to work on that project. A project can have a total time or by task estimate. An estimate_by value of 'none' represents a total time estimate. An estimate_by value of 'customfields' represents an estimate that uses a customfield for individual task estimates. If the estimate is by custom field, the estimate_by__id field must contain the custom field id. A project can only have one active estimate at a time.

The following is a list of the properties that belong to an estimate object, and a description of each.

id
read-only
Int ID of this estimate.
project_id
write-once
Int The project that this estimate belongs to.
active
read-write
Boolean True or false. If false, this estimate is considered deleted.
created
read
String Date/time when this estimate was created, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm).
last_modified
read
String Date/time when this estimate was last modified, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm).
estimate_by
write-once
String The estimate type. One of 'none' or 'customfields'.
estimate_by__id
write-once
Int The customfield id if estimate_by is 'customfields'.

Retrieve Estimates

Example: Retrieve a list of estimates based on the provided filter.

Request

curl "https://rest.tsheets.com/api/v1/estimates" \
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/estimates");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/estimates")
Dim request = New RestRequest(Method.[GET])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/estimates")
  .get()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/estimates",
  "method": "GET",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'GET',
  url: 'https://rest.tsheets.com/api/v1/estimates',
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/estimates');
$request->setMethod(HTTP_METH_GET);

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/estimates")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/estimates"

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/estimates"

  req, _ := http.NewRequest("GET", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/estimates")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest, completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/estimates"; 

$client->GET($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
    "results": {
        "estimates": {
            "840923": {
                "id": 840923,
                "project_id": 1301299,
                "active": true,
                "created": "2019-09-11T15:26:08+00:00",
                "last_modified": "2019-09-11T15:26:08+00:00",
                "estimate_by": "customfields",
                "estimate_by__id": 1247597
            }
        }
    },
    "supplemental_data": {
        "projects": {
            "1301299": {
                "id": 1301299,
                "jobcode_id": 11988623,
                "name": "Keyboard",
                "status": "in_progress",
                "description": "",
                "start_date": "",
                "due_date": "",
                "completed_date": "",
                "active": true,
                "last_modified": "2019-09-11T15:21:43+00:00",
                "created": "2019-09-11T15:21:43+00:00"
            }
        },
        "customfields": {
            "1247597": {
                "id": 1247597,
                "active": true,
                "name": "Tasks",
                "short_code": "84379594",
                "required": 0,
                "applies_to": "timesheet",
                "type": "managed-list",
                "regex_filter": "",
                "last_modified": "2019-09-09T21:50:59+00:00",
                "created": "2019-09-09T21:50:59+00:00",
                "required_customfields": [],
                "ui_preference": "drop_down"
            }
        }
    },
    "more": false
}

Retrieves a list of estimates, with optional filters to narrow down the results.

HTTP Request

gethttps://rest.tsheets.com/api/v1/estimates

Filter Parameters

ids
optional
Int Comma-separated list of estimate ids.
active
optional
String 'yes', 'no', or 'both'. Default is 'yes'.
modified_before
optional
String Only estimates modified before this date/time will be returned, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm)
modified_since
optional
String Only estimates modified since this date/time will be returned, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm)
supplemental_data
optional
Boolean 'yes' or 'no'. Default is 'yes'. Indicates whether supplemental data should be returned.
per_page
optional
Int Deprecated. Use limit for new code.
Represents how many results you'd like to retrieve per request. Default is 50. Max is 50.
If a value over 50 is provided, it is ignored, and the max is used.
limit
optional
Int Represents how many results you'd like to retrieve per request. Default is 200. Max is 200.
If present, this value must be: an integer, greater than zero, and not greater than 200.
Setting limit less than 1 or greater than 200 will result in an error.
page
optional
Int Represents the page of results you'd like to retrieve.

Create Estimates

Example: Create a new estimate.

Request Body

{
    "data": [{
        "project_id": 1301299,
        "estimate_by": "customfields",
        "estimate_by__id": 1247597
    }]
}

Request

curl -X POST \
  https://rest.tsheets.com/api/v1/projects \
  -H 'Authorization: Bearer <TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '<REQUEST BODY>'
var client = new RestClient("https://rest.tsheets.com/api/v1/projects");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <TOKEN>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "<REQUEST BODY>", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/projects")
Dim request = New RestRequest(Method.POST)
request.AddHeader("Authorization", "Bearer <TOKEN>")
request.AddHeader("Content-Type", "application/json")
request.AddParameter("application/json", "<REQUEST BODY>", ParameterType.RequestBody);
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<REQUEST BODY>");
Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/projects")
  .post(body)
  .addHeader("Authorization", "Bearer <TOKEN>")
  .addHeader("Content-Type", "application/json")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/estimates",
  "method": "POST",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
    "Content-Type", "application/json",
  },
  "processData": false,
  "data": "<REQUEST BODY>"
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'POST',
  url: 'https://rest.tsheets.com/api/v1/projects',
  headers: 
  { 
     'Authorization': 'Bearer <TOKEN>',
     'Content-Type': 'application/json',
  },
  body: '<REQUEST BODY>',
  json: true };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/projects');
$request->setMethod(HTTP_METH_POST);

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
  'Content-Type' => 'application/json',
));

$request->setBody('<REQUEST BODY>');

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/projects")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <TOKEN>',
request["Content-Type"] = 'application/json',
request.body = "<REQUEST BODY>"

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/projects"

payload = "<REQUEST BODY>"
headers = {
    'Authorization': 'Bearer <TOKEN>',
    'Content-Type': 'application/json',
    }

response = requests.request("POST", url, data=payload, headers=headers)

print(response.text)
package main

import (
  "fmt"
  "strings"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/projects"

  payload := strings.NewReader("<REQUEST BODY>")

  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, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))

}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
   "Content-Type": "application/json",
]
let parameters = <REQUEST BODY> as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/projects")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest,
  completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');
$client->addHeader('Content-Type', 'application/json');

$req = '<REQUEST BODY>';

$url="https://rest.tsheets.com/api/v1/projects"; 

$client->POST($url, $req);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
    "results": {
        "estimates": {
            "1": {
                "_status_code": 200,
                "_status_message": "Created",
                "id": 840923,
                "project_id": 1301299,
                "active": true,
                "created": "2019-09-11T15:26:08+00:00",
                "last_modified": "2019-09-11T15:26:08+00:00",
                "estimate_by": "customfields",
                "estimate_by__id": 1247597
            }
        }
    },
    "supplemental_data": {
        "projects": {
            "1301299": {
                "id": 1301299,
                "jobcode_id": 11988623,
                "parent_jobcode_id": 0,
                "name": "Keyboard",
                "status": "in_progress",
                "description": "",
                "start_date": "",
                "due_date": "",
                "completed_date": "",
                "active": true,
                "last_modified": "2019-09-11T15:21:43+00:00",
                "created": "2019-09-11T15:21:43+00:00",
                "linked_objects": {
                    "notes_read_times": []
                }
            }
        },
        "customfields": {
            "1247597": {
                "id": 1247597,
                "active": true,
                "required": 0,
                "applies_to": "timesheet",
                "type": "managed-list",
                "short_code": "84379594",
                "regex_filter": "",
                "name": "Tasks",
                "last_modified": "2019-09-09T21:50:59+00:00",
                "created": "2019-09-09T21:50:59+00:00",
                "ui_preference": "drop_down",
                "required_customfields": [],
                "show_to_all": false
            }
        }
    }
}

Create one or more TSheets Estimates.

HTTP Request

posthttps://rest.tsheets.com/api/v1/estimates

Properties

Pass an array of Estimate objects as the value to a 'data' property (see example).

project_id
required
Int The project that this estimate belongs to.
estimate_by
required
String The estimate type. One of 'none' or 'customfields'.
estimate_by__id
optional
Int The customfield id if estimate_by is 'customfields'.

For a full list of the properties that may be set on an estimate, see The Estimate Object.

Status Codes

Each estimate that is created will come back with a _status_code and _status_message that will indicate whether the estimate was created successfully. If there was a problem creating an estimate, there may also be an additional field, _status_extra, which will contain more details about the failure.

200 OK. Estimate was created successfully.
417 Expectation Failed. Something was wrong or missing with the properties supplied for this estimate. See the _status_extra value for more detail.

Update Estimates

Example: Edit an estimate.

Request Body

{
  "data": [{
    "id": 840923,
    "active": false
  }]
}

Request

curl -X PUT \
  https://rest.tsheets.com/api/v1/estimates \
  -H 'Authorization: Bearer <TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '<REQUEST BODY>'
var client = new RestClient("https://rest.tsheets.com/api/v1/estimates");
var request = new RestRequest(Method.PUT);
request.AddHeader("Authorization", "Bearer <TOKEN>");
request.AddHeader("Content-Type", "application/json");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/estimates")
Dim request = New RestRequest(Method.PUT)
request.AddHeader("Authorization", "Bearer <TOKEN>")
request.AddHeader("Content-Type", "application/json")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<REQUEST BODY>");
Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/estimates")
  .put(body)
  .addHeader("Authorization", "Bearer <TOKEN>")
  .addHeader("Content-Type", "application/json")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/estimates",
  "method": "PUT",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
    "Content-Type", "application/json",
  },
  "processData": false,
  "data": "<REQUEST BODY>"
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'PUT',
  url: 'https://rest.tsheets.com/api/v1/estimates',
  headers: 
  { 
     'Authorization': 'Bearer <TOKEN>',
     'Content-Type': 'application/json',
  },
  body: '<REQUEST BODY>',
  json: true };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/estimates');
$request->setMethod(HTTP_METH_PUT);

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
  'Content-Type' => 'application/json',
));

$request->setBody('<REQUEST BODY>');

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/estimates")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <TOKEN>',
request["Content-Type"] = 'application/json',
request.body = "<REQUEST BODY>"

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/estimates"

payload = "<REQUEST BODY>"
headers = {
    'Authorization': 'Bearer <TOKEN>',
    'Content-Type': 'application/json',
    }

response = requests.request("PUT", url, data=payload, headers=headers)

print(response.text)
package main

import (
  "fmt"
  "strings"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/estimates"

  payload := strings.NewReader("<REQUEST BODY>")

  req, _ := http.NewRequest("PUT", 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, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))

}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
   "Content-Type": "application/json",
]
let parameters = <REQUEST BODY> as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(
  url: NSURL(string: "http://rest.tsheets.com/api/v1/estimates")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "PUT"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest,
  completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');
$client->addHeader('Content-Type', 'application/json');

$req = '<REQUEST BODY>';

$url="http://rest.tsheets.com/api/v1/estimates"; 

$client->PUT($url, $req);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
    "results": {
        "estimates": {
            "1": {
                "_status_code": 200,
                "_status_message": "Updated",
                "id": 840923,
                "project_id": 1301299,
                "active": false,
                "created": "2019-09-11T15:26:08+00:00",
                "last_modified": "2019-09-11T15:37:25+00:00",
                "estimate_by": "customfields",
                "estimate_by__id": 1247597
            }
        }
    },
    "supplemental_data": {
        "projects": {
            "1301299": {
                "id": 1301299,
                "jobcode_id": 11988623,
                "parent_jobcode_id": 0,
                "name": "Keyboard",
                "status": "in_progress",
                "description": "",
                "start_date": "",
                "due_date": "",
                "completed_date": "",
                "active": true,
                "last_modified": "2019-09-11T15:21:43+00:00",
                "created": "2019-09-11T15:21:43+00:00",
                "linked_objects": {
                    "notes_read_times": []
                }
            }
        },
        "customfields": {
            "1247597": {
                "id": 1247597,
                "active": true,
                "required": 0,
                "applies_to": "timesheet",
                "type": "managed-list",
                "short_code": "84379594",
                "regex_filter": "",
                "name": "Tasks",
                "last_modified": "2019-09-09T21:50:59+00:00",
                "created": "2019-09-09T21:50:59+00:00",
                "ui_preference": "drop_down",
                "required_customfields": [],
                "show_to_all": false
            }
        }
    }
}

Edit one or more TSheets Estimates.

HTTP Request

puthttps://rest.tsheets.com/api/v1/estimates

Properties

Pass an array of estimate objects as the value to a 'data' property (see example).

id
required
Int Id of the estimate to update.

Updating the 'estimate_by' or 'estimate_by__id' fields is not permitted. Instead, archive the existing estimate and create a new one.

For a full list of the properties that may be set on an estimate, see The Estimate Object.

Status Codes

Each estimate that is edited will come back with a _status_code and _status_message that will indicate whether the estimate was edited successfully. If there was a problem creating a estimate, there may also be an additional field, _status_extra, which will contain more details about the failure.

200 OK. Estimate was edited successfully.
417 Expectation Failed. Something was wrong or missing with the properties supplied for this estimate. See the _status_extra value for more detail.

Files

The TSheets API provides methods for uploading, downloading, and managing image files that can be attached to Timesheets. This is especially useful for workers in the field, for example, who may need to provide visual proof of completion of a job, or to document exceptional conditions which may arise while on the clock.

The File Object

Example

{
  "id": 47765,
  "uploaded_by_user_id": 317046,
  "file_name": "IMG_20181004_214839.png",
  "active": true,
  "size": 369302,
  "last_modified": "2018-10-05T03:57:49+00:00",
  "created": "2018-10-05T03:57:49+00:00",
  "linked_objects": {
    "timesheets": [
      "730045"
    ]
  },
  "meta_data": {
    "file_description": "on-site selfie",
    "image_rotation": "0"
  }
}

Following is a list of the properties that belong to a file object, and a description of each.

id
read-only
Int Id of this file.
file_name
read-write
String Name of this file.
file_data
write-only
String Base64 encoded string of this file. May only be set when adding a file. Not displayed in response to a request to list files or in supplemental_data.
uploaded_by_user_id
read-only
Int Id of the user that uploaded this file.
active
read-only
Boolean If false, this file is considered deleted.
size
read-only
Int Size of the file in bytes
created
read-only
String Date/time when this customfield was created, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm).
last_modified
read-only
String Date/time when this customfield was last modified, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm).
linked_objects
read-only
Object This is a key/value map of all the objects linked to this file and the corresponding object ids.
meta_data
read-write
JSON Object This is a key/value map of any additional data associated with this file. List of allowed keys:
  • file_description: String Description of this file.
  • image_rotation: Int Original image orientation in degrees. Accepted values are: 0 (top), 90 (right), 180 (bottom), 270 (left).

Retrieve Files

Example: Retrieve a list of all files.

Request

curl "https://rest.tsheets.com/api/v1/files" \
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/files");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/files")
Dim request = New RestRequest(Method.[GET])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/files")
  .get()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/files",
  "method": "GET",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'GET',
  url: 'https://rest.tsheets.com/api/v1/files',
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/files');
$request->setMethod(HTTP_METH_GET);

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/files")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/files"

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/files"

  req, _ := http.NewRequest("GET", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/files")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest, completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/files"; 

$client->GET($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Example: Retrieve a list of all files (active or deleted) linked to timesheet with given id.

Request

curl "https://rest.tsheets.com/api/v1/files?linked_object_type=timesheet&object_ids=21718670" \
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/files?linked_object_type=timesheet&object_ids=21718670");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/files?linked_object_type=timesheet&object_ids=21718670")
Dim request = New RestRequest(Method.[GET])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/files?linked_object_type=timesheet&object_ids=21718670")
  .get()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/files?linked_object_type=timesheet&object_ids=21718670",
  "method": "GET",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'GET',
  url: 'https://rest.tsheets.com/api/v1/files',
  qs: {
    linked_object_type: 'timesheet',
    object_ids: '21718670',
  },
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/files');
$request->setMethod(HTTP_METH_GET);

$request->setQueryData(array(
  'linked_object_type' => 'timesheet',
  'object_ids' => '21718670',
));

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/files?linked_object_type=timesheet&object_ids=21718670")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/files"

querystring = {
  "linked_object_type":"timesheet",
  "object_ids":"21718670",
}

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/files?linked_object_type=timesheet&object_ids=21718670"

  req, _ := http.NewRequest("GET", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/files?linked_object_type=timesheet&object_ids=21718670")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest, completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/files?linked_object_type=timesheet&object_ids=21718670"; 

$client->GET($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "files": {
      "44878": {
        "id": 44878,
        "uploaded_by_user_id": 19128,
        "file_name": "tsheets.jpeg",
        "active": true,
        "size": 7890,
        "last_modified": "2018-07-03T17:46:58+00:00",
        "created": "2018-07-03T17:46:58+00:00",
        "linked_objects": {
          "timesheets": [
            "135288482",
            "135288514",
            "135288460"
          ]
        },
        "meta_data": {
          "file_description": "Excellent app to track time"
        }
      },
      "44174": {
        "id": 44174,
        "uploaded_by_user_id": 19128,
        "file_name": "relentless.jpeg",
        "active": true,
        "size": 34900,
        "last_modified": "2018-07-03T17:47:53+00:00",
        "created": "2018-07-03T17:47:53+00:00",
        "linked_objects": [],
        "meta_data": {
          "file_description": "Passionate about our clients success!"
        }
      },
      "50692": {
        "id": 50692,
        "uploaded_by_user_id": 19128,
        "file_name": "healthy.jpg",
        "active": true,
        "size": 4560,
        "last_modified": "2018-08-24T00:09:32+00:00",
        "created": "2018-08-24T00:09:32+00:00",
        "linked_objects": {
          "timesheets": [
            "135288482",
            "135288514",
            "135288460"
          ]
        },
        "meta_data": {
          "file_description": "Work hard period play hard period!"
        }
      }
    }
  },
  "supplemental_data": {
    "users": {
      "19128": {
        "id": 19128,
        "first_name": "Shree",
        "last_name": "Yalamanchili",
        "group_id": 0,
        "active": true,
        ...
      }
    },
    "timesheets": {
      "135288482": {
        "id": 135288482,
        "user_id": 1242515,
        "jobcode_id": 17288283,
        "start": "2018-07-16T09:04:00-06:00",
        "end": "2018-07-16T15:57:00-06:00",
        ...
      },
      "135288514": {
        "id": 135288514,
        "user_id": 1242509,
        "jobcode_id": 18080900,
        "start": "2018-07-16T13:07:00-06:00",
        "end": "2018-07-16T17:29:00-06:00",
        ...
      },
      "135288460": {
        "id": 135288460,
        "user_id": 1242509,
        "jobcode_id": 18080900,
        "start": "2018-07-18T08:09:00-06:00",
        "end": "2018-07-18T14:58:00-06:00",
        ...
      }
    }
  }
}

Retrieves a list of all uploaded files, with optional filters to narrow down the results.

HTTP Request

gethttps://rest.tsheets.com/api/v1/files

Filter Parameters

ids
optional
Int Comma separated list of one or more file ids you'd like to filter on.
uploaded_by_user_ids
optional
Int Comma separated list of one or more user ids you'd like to filter on. Only files uploaded by these users will be returned. If uploaded_by_user_ids is not set, it will default to return files uploaded by the current user making the api request.
linked_object_type
optional
String Only files linked to this object type are returned. Allowed values: 'timesheet'.
object_ids
optional
Int Comma separated list of one or more linked object ids you'd like to filter on.
active
optional
String 'yes', 'no', or 'both'. Default is 'yes'.
modified_before
optional
String Only files modified before this date/time will be returned, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm).
modified_since
optional
String Only files modified since this date/time will be returned, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm).
supplemental_data
optional
String 'yes' or 'no'. Default is 'yes'. Indicates whether supplemental data should be returned.
per_page
optional
Int Deprecated. Use limit for new code.
Represents how many results you'd like to retrieve per request. Default is 50. Max is 50.
If a value over 50 is provided, it is ignored, and the max is used.
limit
optional
Int Represents how many results you'd like to retrieve per request. Default is 200. Max is 200.
If present, this value must be: an integer, greater than zero, and not greater than 200.
Setting limit less than 1 or greater than 200 will result in an error.
page
optional
Int Represents the page of results you'd like to retrieve. Default is 1.

Upload Files

Example: Upload a file.

Request Body

{
 "data":
  [
    {
     "file_data":"data:image/png;base64,iVBORw0KGgoAAA...< actual data here >...ANI=",
     "file_name":"invisible_minion.png",   
     "meta_data": {
           "file_description":"Ba-ba-ba-ba-ba-nana",
           "image_rotation": 0
     }
    }
  ]
}

Request

curl -X POST \
  https://rest.tsheets.com/api/v1/files \
  -H 'Authorization: Bearer <TOKEN>' \
  -H 'Content-Type: application/json' \
  -H 'Content-Length: <LENGTH>' \
  -d '<REQUEST BODY>'
var client = new RestClient("https://rest.tsheets.com/api/v1/files");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <TOKEN>");
request.AddHeader("Content-Type", "application/json");
request.AddHeader("Content-Length", "<LENGTH>");
request.AddParameter("application/json", "<REQUEST BODY>", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/files")
Dim request = New RestRequest(Method.POST)
request.AddHeader("Authorization", "Bearer <TOKEN>")
request.AddHeader("Content-Type", "application/json")
request.AddHeader("Content-Length", "<LENGTH>")
request.AddParameter("application/json", "<REQUEST BODY>", ParameterType.RequestBody);
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<REQUEST BODY>");
Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/files")
  .post(body)
  .addHeader("Authorization", "Bearer <TOKEN>")
  .addHeader("Content-Type", "application/json")
  .addHeader("Content-Length", "<LENGTH>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/files?linked_object_type=timesheet&object_ids=21718670",
  "method": "POST",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
    "Content-Type", "application/json",
    "Content-Length", "<LENGTH>",
  },
  "processData": false,
  "data": "<REQUEST BODY>"
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'POST',
  url: 'https://rest.tsheets.com/api/v1/files',
  headers: 
  { 
     'Authorization': 'Bearer <TOKEN>',
     'Content-Type': 'application/json',
     'Content-Length': '<LENGTH>',
  },
  body: '<REQUEST BODY>',
  json: true };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/files');
$request->setMethod(HTTP_METH_POST);

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
  'Content-Type' => 'application/json',
  'Content-Length' => '<LENGTH>',
));

$request->setBody('<REQUEST BODY>');

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/files")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <TOKEN>',
request["Content-Type"] = 'application/json',
request["Content-Length"] = '<LENGTH>',
request.body = "<REQUEST BODY>"

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/files"

payload = "<REQUEST BODY>"
headers = {
    'Authorization': 'Bearer <TOKEN>',
    'Content-Type': 'application/json',
    'Content-Length': '<LENGTH>',
    }

response = requests.request("POST", url, data=payload, headers=headers)

print(response.text)
package main

import (
  "fmt"
  "strings"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/files"

  payload := strings.NewReader("<REQUEST BODY>")

  req, _ := http.NewRequest("POST", url, payload)

  req.Header.Add("Authorization", "Bearer <TOKEN>")
  req.Header.Add("Content-Type", "application/json")
  req.Header.Add("Content-Length", "<LENGTH>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))

}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
   "Content-Type": "application/json",
   "Content-Length": "<LENGTH>",
]
let parameters = <REQUEST BODY> as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/files")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest,
  completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');
$client->addHeader('Content-Type', 'application/json');
$client->addHeader('Content-Length', '<LENGTH>');

$req = '<REQUEST BODY>';

$url="https://rest.tsheets.com/api/v1/files"; 

$client->POST($url, $req);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "files": {
      "1": {
        "_status_code": 200,
        "_status_message": "Uploaded",
        "id": 123828,
        "uploaded_by_user_id": 19128,
        "file_name": "invisible_minion.png",
        "active": true,
        "size": 95,
        "last_modified": "2018-08-24T00:09:32+00:00",
        "created": "2018-08-24T00:09:32+00:00",
        "linked_objects": [],
        "meta_data": {
          "file_description": "Ba-ba-ba-ba-ba-nana",
          "image_rotation": 0
        }
      }
    }
  },
  "supplemental_data": {
    "users": {
      "19128": {
        "id": 19128,
        "first_name": "Shree",
        "last_name": "Yalamanchili",
        "group_id": 0,
        "active": true,
        ...
      }
    }
  }
} 

Add one or more files that can be attached to objects. Currently we only allow .png, .jpeg, .jpg file formats.

HTTP Request

posthttps://rest.tsheets.com/api/v1/files

Properties

Pass an array of file objects as the value to a 'data' property (see example).

file_name
required
String Name of the file.
file_data
required
String Base64 encoded string of the file.

For a full list of the properties that may be set on a file, see the File object.

Status Codes

Each file that is uploaded will come back with a _status_code and _status_message that will indicate whether the file was uploaded successfully. If there was a problem uploading a file, there may also be an additional field, _status_extra, which will contain more details about the failure.

200 OK. File was uploaded successfully.
417 Expectation Failed. Something was wrong or missing with the properties supplied for this file. See the _status_extra value for more detail.

Update Files

Example: Update a file.

Request Body

{
 "data":
  [
    {
     "id":"123455",   
     "meta_data": {
           "file_description":"Testing PUT request",
           "image_rotation": 180
     }
    }
  ]
}

Request

curl -X PUT \
  https://rest.tsheets.com/api/v1/files \
  -H 'Authorization: Bearer <TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '<REQUEST BODY>'
var client = new RestClient("https://rest.tsheets.com/api/v1/files");
var request = new RestRequest(Method.PUT);
request.AddHeader("Authorization", "Bearer <TOKEN>");
request.AddHeader("Content-Type", "application/json");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/files")
Dim request = New RestRequest(Method.PUT)
request.AddHeader("Authorization", "Bearer <TOKEN>")
request.AddHeader("Content-Type", "application/json")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<REQUEST BODY>");
Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/files")
  .put(body)
  .addHeader("Authorization", "Bearer <TOKEN>")
  .addHeader("Content-Type", "application/json")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/files?linked_object_type=timesheet&object_ids=21718670",
  "method": "PUT",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
    "Content-Type", "application/json",
  },
  "processData": false,
  "data": "<REQUEST BODY>"
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'PUT',
  url: 'https://rest.tsheets.com/api/v1/files',
  headers: 
  { 
     'Authorization': 'Bearer <TOKEN>',
     'Content-Type': 'application/json',
  },
  body: '<REQUEST BODY>',
  json: true };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/files');
$request->setMethod(HTTP_METH_PUT);

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
  'Content-Type' => 'application/json',
));

$request->setBody('<REQUEST BODY>');

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/files")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <TOKEN>',
request["Content-Type"] = 'application/json',
request.body = "<REQUEST BODY>"

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/files"

payload = "<REQUEST BODY>"
headers = {
    'Authorization': 'Bearer <TOKEN>',
    'Content-Type': 'application/json',
    }

response = requests.request("PUT", url, data=payload, headers=headers)

print(response.text)
package main

import (
  "fmt"
  "strings"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/files"

  payload := strings.NewReader("<REQUEST BODY>")

  req, _ := http.NewRequest("PUT", 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, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))

}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
   "Content-Type": "application/json",
]
let parameters = <REQUEST BODY> as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(
  url: NSURL(string: "http://rest.tsheets.com/api/v1/files")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "PUT"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest,
  completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');
$client->addHeader('Content-Type', 'application/json');

$req = '<REQUEST BODY>';

$url="http://rest.tsheets.com/api/v1/files"; 

$client->PUT($url, $req);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "files": {
      "123455": {
        "_status_code": 200,
        "_status_message": "Updated",
        "id": 123455,
        "uploaded_by_user_id": 19128,
        "file_name": "invisible_minion.png",
        "active": true,
        "size": 95,
        "last_modified": "2018-09-19T00:09:32+00:00",
        "created": "2018-08-24T00:09:32+00:00",
        "linked_objects": [],
        "meta_data": {
          "file_description": "Testing PUT request",
          "image_rotation": 180
        }
      }
    }
  },
  "supplemental_data": {
    "users": {
      "19128": {
        "id": 19128,
        "first_name": "Shree",
        "last_name": "Yalamanchili",
        "group_id": 0,
        "active": true,
        ...
      }
    }
  }
}

Edit one or more files that are attached to objects.

HTTP Request

puthttps://rest.tsheets.com/api/v1/files

Properties

Pass an array of file objects as the value to a 'data' property (see example).

When editing a file, you must uniquely identify the file by passing in its id. All other properties defined below may be passed in to the request with a new value in order to change it. If the value passed in is the same as it was previously, or if a particular property is not passed in at all, it will be ignored.

id
required
Int Id of the file to edit.
file_name
optional
String Name of this file the file to edit.
meta_data
read-write
JSON Object This is a key/value map of any additional data associated with this file. List of allowed keys:
  • file_description: String Description of this file.
  • image_rotation: Int Original image orientation in degrees. Accepted values are: 0 (top), 90 (right), 180 (bottom), 270 (left).

Status Codes

Each file that is updated will come back with a _status_code and _status_message that will indicate whether the file was updated successfully. If there was a problem updating a file, there may also be an additional field, _status_extra, which will contain more details about the failure.

200 OK. File was updated successfully.
404 Not Found. File either has never existed or has been deleted.
417 Expectation Failed. Something was wrong or missing with the properties supplied for this file. See the _status_extra value for more detail.

Download a File

Example: The following request returns a .jpg object.

Request

curl "https://rest.tsheets.com/api/v1/files/raw?id=123828" \
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/files/raw?id=123828");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/files/raw?id=123828")
Dim request = New RestRequest(Method.[GET])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/files/raw?id=123828")
  .get()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/files/raw?id=123828",
  "method": "GET",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'GET',
  url: 'https://rest.tsheets.com/api/v1/files/raw',
  qs: {
    id: '123828',
  },
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/files/raw');
$request->setMethod(HTTP_METH_GET);

$request->setQueryData(array(
  'id' => '123828',
));

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/files/raw?id=123828")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/files/raw"

querystring = {
  "id":"123828",
}

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/files/raw?id=123828"

  req, _ := http.NewRequest("GET", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/files/raw?id=123828")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest, completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/files/raw?id=123828"; 

$client->GET($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

Content-Type: application/octet-stream
Content-Length: 95
Content-Disposition: attachment; filename="invisible_minion.jpg"
Cache-Control: max-age=86400

[95 bytes of object data]

Download a file in raw binary format.

HTTP Request

gethttps://rest.tsheets.com/api/v1/files/raw

Parameters

id
required
Int Id of the file to download.

Response

The raw bytes of the file are returned, and the Content-Type header is set to a binary media type of 'application/octet-stream'.

Delete Files

Example: Request to delete four files. Two succeed and two fail.

Request

curl -X DELETE "https://rest.tsheets.com/api/v1/files?ids=129526,129524,13455,89999"
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/files?ids=129526,129524,13455,89999");
var request = new RestRequest(Method.DELETE);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/files?ids=129526,129524,13455,89999")
Dim request = New RestRequest(Method.[DELETE])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/files?ids=129526,129524,13455,89999")
  .delete()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/files?ids=129526,129524,13455,89999",
  "method": "DELETE",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'DELETE',
  url: 'https://rest.tsheets.com/api/v1/files',
  qs: {
    ids: '129526,129524,13455,89999',
  },
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/files');
$request->setMethod(HTTP_METH_DELETE);

$request->setQueryData(array(
  'ids' => '129526,129524,13455,89999',
));

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/files?ids=129526,129524,13455,89999")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Delete.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/files"

querystring = {
  "ids":"129526,129524,13455,89999",
}

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/files?ids=129526,129524,13455,89999"

  req, _ := http.NewRequest("DELETE", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/files?ids=129526,129524,13455,89999")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "DELETE"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/files?ids=129526,129524,13455,89999"; 

$client->DELETE($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
 "results": {
  "files": {
   "129526": {
    "_status_code": 200,
    "_status_message": "OK, deleted",
    "id": "129526"
   },
   "129524": {
    "_status_code": 200,
    "_status_message": "OK, deleted",
    "id": "129524"
   },
   "13455": {
    "_status_code": 404,
    "_status_message": "File not found!",
    "id": "13455"
   },
   "89999": {
    "_status_code": 404,
    "_status_message": "File not found!",
    "id": "89999"
   }
  }
 }
}

Delete one or more files.

HTTP Request

deletehttps://rest.tsheets.com/api/v1/files

Parameters

If no filters are specified at all, no files are deleted.

ids
optional
Int Comma separated list of file ids you'd like to delete.

Status Codes

Each file that is deleted will come back with a _status_code and _status_message that will indicate whether the file was deleted successfully. If there was a problem deleting a file, there may also be an additional field, _status_extra which will contain more details about the failure.

200 OK. File was deleted successfully.
417 Expectation Failed. Something went wrong for this file. See the _status_extra value for more detail.

Geofence Configs

The Geofence Config Object

Example

{
  "id": 151,
  "type": "location",
  "type_id": 282316,
  "active": true,
  "enabled": true,
  "radius": 150,
  "last_modified": "2017-09-07T19:09:26+00:00",
  "created": "2017-09-07T19:09:26+00:00"
}

Following is a list of the properties that belong to a geofence config object, and a description of each.

id
read-only
Int Id of geofence config.
type
read-write
String 'location'. The type of entity the geofence config is related to.
type_id
read-write
Int The id of the entity the geofence config is related to.
active
read-write
Boolean If true, this geofence config is active. If false, this geofence config is archived.
enabled
read-write
Boolean true or false. Indicates whether a geofence for the associated entity should be enabled.
radius
read-write
Int Configures the size of the geofence.
last_modified
read-only
String Date/time when this geofence config was last modified, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm).
created
read-only
String Date/time when this geofence config was created, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm).

Retrieve Geofence Configs

Example: Retrieve a list of all geofence configs for the current client.

Request

curl "https://rest.tsheets.com/api/v1/geofence_configs" \
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/geofence_configs");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/geofence_configs")
Dim request = New RestRequest(Method.[GET])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/geofence_configs")
  .get()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/geofence_configs",
  "method": "GET",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'GET',
  url: 'https://rest.tsheets.com/api/v1/geofence_configs',
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/geofence_configs');
$request->setMethod(HTTP_METH_GET);

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/geofence_configs")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/geofence_configs"

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/geofence_configs"

  req, _ := http.NewRequest("GET", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/geofence_configs")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest, completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/geofence_configs"; 

$client->GET($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "geofence_configs": {
      "151": {
        "id": 151,
        "type": "locations",
        "type_id": 282316,
        "active": true,
        "enabled": true,
        "radius": 150,
        "last_modified": "2017-09-07T19:09:26+00:00",
        "created": "2017-09-07T19:09:26+00:00"
      },
      "297": {
        "id": 297,
        "type": "locations",
        "type_id": 323445,
        "active": true,
        "enabled": false,
        "radius": 125,
        "last_modified": "2017-09-11T13:11:14+00:00",
        "created": "2017-09-11T13:11:14+00:00"
      }
    }
  },
  "more": false,
  "supplemental_data": {
    "locations": {
      "282316": {
        "id": 282316,
        "addr1": "1234 W Way St",
        "addr2": "",
        "city": "Eagle",
        "state": "Idaho",
        "zip": "83714",
        "country": "US",
        "active": true,
        "latitude": 43.62122110,
        "longitude": -116.34932150,
        "place_id": "",
        "place_id_hash": "8c43103323bb0b1ce7c4094029029914",
        "label": "1234 W Way St Eagle, Idaho 83714 US",
        "notes": "",
        "geocoding_status": "complete",
        "created": "2018-07-12T21:13:14+00:00",
        "last_modified": "2018-07-12T21:13:14+00:00",
        "linked_objects": {},
        "geofence_config_id": 151
      },
      "323445": {
        "id": 323445,
        "addr1": "5678 E End St",
        "addr2": "",
        "city": "Eagle",
        "state": "Idaho",
        "zip": "83714",
        "country": "US",
        "active": true,
        "latitude": -33.87904780,
        "longitude": 151.21133580,
        "place_id": "",
        "place_id_hash": "f6933fee56d6cd9e02d1dbff1a551cfa",
        "label": "5678 E End St Eagle, Idaho 83714 US",
        "notes": "",
        "geocoding_status": "complete",
        "created": "2018-07-12T21:13:14+00:00",
        "last_modified": "2018-07-12T21:13:14+00:00",
        "linked_objects": {
          "jobcodes": [
            2589531
          ]
        },
        "geofence_config_id": 297
      }
    }
  }
}

Retrieves a list of all geofence configs, with optional filters to narrow down the results.

HTTP Request

gethttps://rest.tsheets.com/api/v1/geofence_configs

Filter Parameters

ids
optional
Int Comma separated list of one or more geofence config ids you'd like to filter on. Only geofence configs with an id set to one of these values will be returned. If omitted, all geofence configs matching other specified filters are returned.
type
optional
String Comma separated list of one or more types. If specified only geofence configs of that type will be returned.
type_ids
optional
Int Comma separated list of one or more type ids you'd like to filter on. Only geofence configs with a type_id set to one of these values will be returned.
enabled
optional
Boolean true or false. If specified only geofence configs with matching enabled values will be returned.
active
optional
String 'yes', 'no', or 'both'. Default is 'yes'.
modified_before
optional
String Only geofence configs modified before this date/time will be returned, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm).
modified_since
optional
String Only geofence configs modified since this date/time will be returned, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm).
supplemental_data
optional
String 'yes' or 'no'. Default is 'yes'. Indicates whether supplemental data should be returned.
per_page
optional
Int Deprecated. Use limit for new code.
Represents how many results you'd like to retrieve per request. Default is 50. Max is 50.
If a value over 50 is provided, it is ignored, and the max is used.
limit
optional
Int Represents how many results you'd like to retrieve per request. Default is 200. Max is 200.
If present, this value must be: an integer, greater than zero, and not greater than 200.
Setting limit less than 1 or greater than 200 will result in an error.
page
optional
Int Represents the page of results you'd like to retrieve. Default is 1.
by_jobcode_assignment
optional
Boolean true or false. If specified, only geofence configs related to a location that is mapped to a jobcode the user is assigned to will be returned.

Geolocations

The Geolocation Object

Example

{
  "id": 185648268,
  "user_id": 29474,
  "accuracy": 21,
  "altitude": 0,
  "latitude": 43.6866258,
  "longitude": -116.3516646,
  "device_identifier": "",
  "source": "gps",
  "heading": 0,
  "speed": 0,  
  "created": "2018-08-16T17:56:57+00:00"
}

Following is a list of the properties that belong to a geolocation, and a description of each.

id
read-only
Int Id of geolocation.
user_id
read-write
Int User id for the user that this geolocation belongs to.
accuracy
read-write
Float Indicates the radius of accuracy around the geolocation in meters.
altitude
read-write
Float Indicates the altitude of the geolocation in meters.
latitude
read-write
Float Indicates the latitude of the geolocation in degrees.
longitude
read-write
Float Indicates the longitude of the geolocation in degrees.
speed
read-write
Float Indicates the speed of travel (meters per second) when the geolocation was recorded.
heading
read-write
Int Indicates the heading of the geolocation in degrees.
source
read-write
String Indicates how the GPS point was obtained. One of 'gps', 'wifi', or 'cell'.
device_identifier
read-write
String Unique identifier (for the given client) for the device associated with this geolocation.
created
read-write
String Date/time when this geolocation was created, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm)

Retrieve Geolocations

Example: Retrieve a list of all geolocations modified since a given date.

Request

curl "https://rest.tsheets.com/api/v1/geolocations?modified_since=2018-08-01T12:00:00-06:00" \
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/geolocations?modified_since=2018-08-01T12:00:00-06:00");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/geolocations?modified_since=2018-08-01T12:00:00-06:00")
Dim request = New RestRequest(Method.[GET])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/geolocations?modified_since=2018-08-01T12:00:00-06:00")
  .get()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/geolocations?modified_since=2018-08-01T12:00:00-06:00",
  "method": "GET",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'GET',
  url: 'https://rest.tsheets.com/api/v1/geolocations',
  qs: {
    modified_since: '2018-08-01T12:00:00-06:00',
  },
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/geolocations');
$request->setMethod(HTTP_METH_GET);

$request->setQueryData(array(
  'modified_since' => '2018-08-01T12:00:00-06:00',
));

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/geolocations?modified_since=2018-08-01T12:00:00-06:00")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/geolocations"

querystring = {
  "modified_since":"2018-08-01T12:00:00-06:00",
}

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/geolocations?modified_since=2018-08-01T12:00:00-06:00"

  req, _ := http.NewRequest("GET", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/geolocations?modified_since=2018-08-01T12:00:00-06:00")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest, completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/geolocations?modified_since=2018-08-01T12:00:00-06:00"; 

$client->GET($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "geolocations": {
      "185648268": {
      "id": 185648268,
      "user_id": 29474,
      "accuracy": 21.2357,
      "altitude": 0,
      "latitude": 43.6866258,
      "longitude": -116.3516646,
      "device_identifier": "",
      "source": "gps",
      "heading": 0,
      "speed": 0,        
      "created": "2018-08-16T17:56:57+00:00"
    },
    "185648270": {
      "id": 185648270,
      "user_id": 29474,
      "accuracy": 20.375,
      "altitude": 0,
      "latitude": 43.6866377,
      "longitude": -116.3516499,
      "device_identifier": "",
      "source": "gps",
      "heading": 0,
      "speed": 0,        
      "created": "2018-08-16T17:57:24+00:00"
    },
    "185648320": {
      "id": 185648320,
      "user_id": 29474,
      "accuracy": 20.375,
      "altitude": 0,
      "latitude": 43.6866377,
      "longitude": -116.3516499,
      "device_identifier": "",
      "source": "gps",
      "heading": 0,
      "speed": 0,        
      "created": "2018-08-16T17:57:27+00:00"
    },
    ...
  }
}

Retrieves a list of geolocations associated with your company, with filters to narrow down the results.

HTTP Request

gethttps://rest.tsheets.com/api/v1/geolocations

Filter Parameters

ids
required (unless modified_before or modified_since is set)
Int Comma separated list of one or more geolocation ids you'd like to filter on. Only geolocations with an id set to one of these values will be returned.
modified_before
required (unless ids or modified_since is set)
String Only geolocations modified before this date/time will be returned, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm)
modified_since
required unless ids or modified_before is set)
String Only geolocations modified since this date/time will be returned, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm)
user_ids
optional
Int A comma-separated list of user ids. Only geolocations linked to these users will be returned.
group_ids
optional
Int A comma-separated list of group ids. Only geolocations linked to users from these groups will be returned.
supplemental_data
optional
String 'yes' or 'no'. Default is 'yes'. Indicates whether supplemental data should be returned.
per_page
optional
Int Deprecated. Use limit for new code.
Represents how many results you'd like to retrieve per request. Default is 50. Max is 50.
If a value over 50 is provided, it is ignored, and the max is used.
limit
optional
Int Represents how many results you'd like to retrieve per request. Default is 200. Max is 200.
If present, this value must be: an integer, greater than zero, and not greater than 200.
Setting limit less than 1 or greater than 200 will result in an error.
page
optional
Int Represents the page of results you'd like to retrieve. Default is 1.

Create Geolocations

Example: Create two new geolocations.

Request Body

{
  "data":
  [
    {
      "created": "2018-08-19T11:30:09-06:00",
      "user_id": 1242515,
      "accuracy": 20.375,
      "altitude": 0,
      "latitude": 43.68662580,
      "longitude": -116.35166460
    },
    {
      "created": "2018-08-19T12:38:56-06:00",
      "user_id": 1242515,
      "accuracy": 20.375,
      "altitude": 0,
      "latitude": 43.68692580,
      "longitude": -116.35169460
    }
  ]
}

Request

curl -X POST \
  https://rest.tsheets.com/api/v1/geolocations \
  -H 'Authorization: Bearer <TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '<REQUEST BODY>'
var client = new RestClient("https://rest.tsheets.com/api/v1/geolocations");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <TOKEN>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "<REQUEST BODY>", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/geolocations")
Dim request = New RestRequest(Method.POST)
request.AddHeader("Authorization", "Bearer <TOKEN>")
request.AddHeader("Content-Type", "application/json")
request.AddParameter("application/json", "<REQUEST BODY>", ParameterType.RequestBody);
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<REQUEST BODY>");
Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/geolocations")
  .post(body)
  .addHeader("Authorization", "Bearer <TOKEN>")
  .addHeader("Content-Type", "application/json")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/geolocations?modified_since=2018-08-01T12:00:00-06:00",
  "method": "POST",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
    "Content-Type", "application/json",
  },
  "processData": false,
  "data": "<REQUEST BODY>"
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'POST',
  url: 'https://rest.tsheets.com/api/v1/geolocations',
  headers: 
  { 
     'Authorization': 'Bearer <TOKEN>',
     'Content-Type': 'application/json',
  },
  body: '<REQUEST BODY>',
  json: true };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/geolocations');
$request->setMethod(HTTP_METH_POST);

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
  'Content-Type' => 'application/json',
));

$request->setBody('<REQUEST BODY>');

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/geolocations")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <TOKEN>',
request["Content-Type"] = 'application/json',
request.body = "<REQUEST BODY>"

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/geolocations"

payload = "<REQUEST BODY>"
headers = {
    'Authorization': 'Bearer <TOKEN>',
    'Content-Type': 'application/json',
    }

response = requests.request("POST", url, data=payload, headers=headers)

print(response.text)
package main

import (
  "fmt"
  "strings"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/geolocations"

  payload := strings.NewReader("<REQUEST BODY>")

  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, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))

}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
   "Content-Type": "application/json",
]
let parameters = <REQUEST BODY> as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/geolocations")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest,
  completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');
$client->addHeader('Content-Type', 'application/json');

$req = '<REQUEST BODY>';

$url="https://rest.tsheets.com/api/v1/geolocations"; 

$client->POST($url, $req);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "geolocations": {
      "1": {
        "_status_code": 200,
        "_status_message": "Created",
        "id": 185899164,
        "user_id": 1242515,
        "accuracy": 20,
        "altitude": 0,
        "latitude": 43.6866258,
        "longitude": -116.3516646,
        "created": "2018-08-19T17:30:09+00:00"
    },
      "2": {
        "_status_code": 200,
        "_status_message": "Created",
        "id": 185899166,
        "user_id": 1242515,
        "accuracy": 20,
        "altitude": 0,
        "latitude": 43.6869258,
        "longitude": -116.3516946,
        "created": "2018-08-19T18:38:56+00:00"
      }
    }
  },
  "supplemental_data": {
    "users": {
      "1242515": {
        "id": 1242515,
        "first_name": "Alexander",
        "last_name": "Luzzana",
        "group_id": 144959,
        "active": true,
        ...
      }
    }
  }
}

HTTP Request

posthttps://rest.tsheets.com/api/v1/geolocations

Properties

Pass an array of geolocation objects as the value to a 'data' property (see example).

created
required
String Date/time of creation for this geolocation, in ISO 8601 format
user_id
required
Int User id for the user that this timesheet belongs to.
accuracy
required
Float Indicates the radius of accuracy around the geolocation in meters.
altitude
required
Float Indicates the altitude of the geolocation in meters. Enter 0 if altitude is unknown.
latitude
required
Float Indicates the latitude of the geolocation in degrees.
longitude
required
Float Indicates the longitude of the geolocation in degrees.
device_identifier
optional
String Unique identifier (for the given client) for the device associated with this geolocation.

For a full list of properties that may be set on a geolocation, see the Geolocation object.

Status Codes

Each geolocation that is created will come back with a _status_code and _status_message that will indicate whether the geolocation was created successfully. If there was a problem creating a geolocation, there may also be an additional field, _status_extra, which will contain more details about the failure.

200 OK. geolocation was created successfully.
202 OK. geolocation was accepted, but not created (because we already have a geolocation with all the same characteristics as the submitted one)
417 Expectation Failed. Something was wrong or missing with the properties supplied for this geolocation. See the _status_extra value for more detail.

Groups

The Group Object

Example

{
  "id": 6,
  "active": true,
  "name": "Group 1",
  "last_modified": "2018-08-19T16:29:28+00:00",
  "created": "2018-08-19T16:29:28+00:00",
  "manager_ids": [
    "300",
    "316"
  ]
}

Following is a list of the properties that belong to a group object, and a description of each.

id
read-only
Int ID of this group.
active
read-write
Boolean true or false. If false, this group is considered archived.
name
read-write
String Name associated with this group
last_modified
read-only
String Date/time when this group was last modified, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm)
created
read-only
String Date/time when this group was created, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm)
manager_ids
read-write
Array List of id's for the users allowed to manage this group

Retrieve Groups

Example: Retrieve a list of all active groups.

Request

curl "https://rest.tsheets.com/api/v1/groups" \
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/groups");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/groups")
Dim request = New RestRequest(Method.[GET])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/groups")
  .get()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/groups",
  "method": "GET",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'GET',
  url: 'https://rest.tsheets.com/api/v1/groups',
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/groups');
$request->setMethod(HTTP_METH_GET);

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/groups")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/groups"

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/groups"

  req, _ := http.NewRequest("GET", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/groups")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest, completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/groups"; 

$client->GET($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Example: Retrieve a list of groups with a given id. Set pagination to 30 results/page.

Request

curl "https://rest.tsheets.com/api/v1/groups?id=6%2C16&limit=30" \
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/groups?id=6%2C16&limit=30");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/groups?id=6%2C16&limit=30")
Dim request = New RestRequest(Method.[GET])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/groups?id=6%2C16&limit=30")
  .get()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/groups?id=6%2C16&limit=30",
  "method": "GET",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'GET',
  url: 'https://rest.tsheets.com/api/v1/groups',
  qs: {
    id: '6%2C16',
    limit: '30',
  },
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/groups');
$request->setMethod(HTTP_METH_GET);

$request->setQueryData(array(
  'id' => '6%2C16',
  'limit' => '30',
));

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/groups?id=6%2C16&limit=30")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/groups"

querystring = {
  "id":"6%2C16",
  "limit":"30",
}

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/groups?id=6%2C16&limit=30"

  req, _ := http.NewRequest("GET", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/groups?id=6%2C16&limit=30")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest, completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/groups?id=6%2C16&limit=30"; 

$client->GET($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "groups": {
      "6": {
        "id": 6,
        "active": true,
        "name": "Group 1",
        "last_modified": "2018-08-19T16:29:28+00:00",
        "created": "2018-08-19T16:29:28+00:00",
        "manager_ids": [
          "300",
          "316"
        ]
      },
      "8": {
        "id": 8,
        "active": true,
        "name": "Group 2",
        "last_modified": "2018-08-19T16:29:35+00:00",
        "created": "2018-08-19T16:29:35+00:00",
        "manager_ids": [
          "316"
        ]
      },
      "16": {
        "id": 16,
        "active": true,
        "name": "Group 3",
        "last_modified": "2018-08-20T23:22:13+00:00",
        "created": "2018-08-20T23:22:13+00:00",
        "manager_ids": []
      }
    }
  },
  "more": false,
  "supplemental_data": {
    "users": {
      "300": {
        "id": 300,
        "first_name": "Joseph",
        "last_name": "",
        "group_id": 0,
        "active": true,
        ...
      },
      "316": {
        "id": 316,
        "first_name": "Bill",
        "last_name": "Franklin",
        "group_id": 0,
        "active": true,
        ...
      }
    }
  }
}

Retrieves a list of all groups associated with your company, with optional filters to narrow down the results.

HTTP Request

gethttps://rest.tsheets.com/api/v1/groups

Filter Parameters

ids
optional
Int Comma separated list of one or more group ids you'd like to filter on.
active
optional
String 'yes', 'no', or 'both'. Default is 'yes'.
manager_ids
optional
Int Comma separated list of one or more manager ids you'd like to filter on.
name
optional
String Comma separated list of one or more group names you'd like to filter on.
modified_before
optional
String Only groups modified before this date/time will be returned, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm)
modified_since
optional
String Only groups modified since this date/time will be returned, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm)
supplemental_data
optional
String 'yes' or 'no'. Default is 'yes'. Indicates whether supplemental data should be returned.
per_page
optional
Int Deprecated. Use limit for new code.
Represents how many results you'd like to retrieve per request. Default is 50. Max is 50.
If a value over 50 is provided, it is ignored, and the max is used.
limit
optional
Int Represents how many results you'd like to retrieve per request. Default is 200. Max is 200.
If present, this value must be: an integer, greater than zero, and not greater than 200.
Setting limit less than 1 or greater than 200 will result in an error.
page
optional
Int Represents the page of results you'd like to retrieve.

Create Groups

Example: Create two new groups.

Request Body

{
  "data":
  [
    {
      "name":"Group 1",
      "manager_ids":"300, 316"
    },
    {
      "name":"Group 2",
      "manager_ids":"316"
    }
  ]
}

Request

curl -X POST \
  https://rest.tsheets.com/api/v1/groups \
  -H 'Authorization: Bearer <TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '<REQUEST BODY>'
var client = new RestClient("https://rest.tsheets.com/api/v1/groups");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <TOKEN>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "<REQUEST BODY>", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/groups")
Dim request = New RestRequest(Method.POST)
request.AddHeader("Authorization", "Bearer <TOKEN>")
request.AddHeader("Content-Type", "application/json")
request.AddParameter("application/json", "<REQUEST BODY>", ParameterType.RequestBody);
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<REQUEST BODY>");
Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/groups")
  .post(body)
  .addHeader("Authorization", "Bearer <TOKEN>")
  .addHeader("Content-Type", "application/json")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/groups?id=6%2C16&limit=30",
  "method": "POST",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
    "Content-Type", "application/json",
  },
  "processData": false,
  "data": "<REQUEST BODY>"
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'POST',
  url: 'https://rest.tsheets.com/api/v1/groups',
  headers: 
  { 
     'Authorization': 'Bearer <TOKEN>',
     'Content-Type': 'application/json',
  },
  body: '<REQUEST BODY>',
  json: true };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/groups');
$request->setMethod(HTTP_METH_POST);

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
  'Content-Type' => 'application/json',
));

$request->setBody('<REQUEST BODY>');

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/groups")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <TOKEN>',
request["Content-Type"] = 'application/json',
request.body = "<REQUEST BODY>"

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/groups"

payload = "<REQUEST BODY>"
headers = {
    'Authorization': 'Bearer <TOKEN>',
    'Content-Type': 'application/json',
    }

response = requests.request("POST", url, data=payload, headers=headers)

print(response.text)
package main

import (
  "fmt"
  "strings"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/groups"

  payload := strings.NewReader("<REQUEST BODY>")

  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, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))

}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
   "Content-Type": "application/json",
]
let parameters = <REQUEST BODY> as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/groups")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest,
  completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');
$client->addHeader('Content-Type', 'application/json');

$req = '<REQUEST BODY>';

$url="https://rest.tsheets.com/api/v1/groups"; 

$client->POST($url, $req);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "groups": {
      "1": {
        "id": 6,
        "name": "Group 1",
        "last_modified": "2018-08-19T16:29:28+00:00",
        "created": "2018-08-19T16:29:28+00:00",
        "manager_ids": [
          "300",
          "316"
        ]
      },
      "2": {
        "id": 8,
        "name": "Group 2",
        "last_modified": "2018-08-19T16:29:35+00:00",
        "created": "2018-08-19T16:29:35+00:00",
        "manager_ids": [
          "316"
        ]
      }
    }
  },
  "more": false,
  "supplemental_data": {
    "users": {
      "300": {
        "id": 300,
        "first_name": "Joseph",
        "last_name": "",
        "group_id": 0,
        "active": true,
        ...
      },
      "316": {
        "id": 316,
        "first_name": "Bill",
        "last_name": "Franklin",
        "group_id": 0,
        "active": true,
        ...
    }
  }
}

Add one or more groups to your company.

HTTP Request

posthttps://rest.tsheets.com/api/v1/groups

Properties

Pass an array of group objects as the value to a 'data' property (see example).

name
required
String Name of the group.

For a full list of properties that may be set on a group, see the Group object.

Status Codes

Each group that is created will come back with a _status_code and _status_message that will indicate whether the group was created successfully. If there was a problem creating a group, there may also be an additional field, _status_extra, which will contain more details about the failure.

200 OK. Group was created successfully.
417 Expectation Failed. Something was wrong or missing with the properties supplied for this group. See the _status_extra value for more detail.

Update Groups

Example: Change the name for each of these groups, and clear the managers of the first one.

Request Body

{
  "data":
  [
    {
      "id": 6,
      "name":"Group 1a",
      "manager_ids":""
    },
    {
      "id": 8,
      "name":"Group 2b"
    }
  ]
}

Request

curl -X PUT \
  https://rest.tsheets.com/api/v1/groups \
  -H 'Authorization: Bearer <TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '<REQUEST BODY>'
var client = new RestClient("https://rest.tsheets.com/api/v1/groups");
var request = new RestRequest(Method.PUT);
request.AddHeader("Authorization", "Bearer <TOKEN>");
request.AddHeader("Content-Type", "application/json");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/groups")
Dim request = New RestRequest(Method.PUT)
request.AddHeader("Authorization", "Bearer <TOKEN>")
request.AddHeader("Content-Type", "application/json")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<REQUEST BODY>");
Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/groups")
  .put(body)
  .addHeader("Authorization", "Bearer <TOKEN>")
  .addHeader("Content-Type", "application/json")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/groups?id=6%2C16&limit=30",
  "method": "PUT",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
    "Content-Type", "application/json",
  },
  "processData": false,
  "data": "<REQUEST BODY>"
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'PUT',
  url: 'https://rest.tsheets.com/api/v1/groups',
  headers: 
  { 
     'Authorization': 'Bearer <TOKEN>',
     'Content-Type': 'application/json',
  },
  body: '<REQUEST BODY>',
  json: true };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/groups');
$request->setMethod(HTTP_METH_PUT);

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
  'Content-Type' => 'application/json',
));

$request->setBody('<REQUEST BODY>');

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/groups")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <TOKEN>',
request["Content-Type"] = 'application/json',
request.body = "<REQUEST BODY>"

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/groups"

payload = "<REQUEST BODY>"
headers = {
    'Authorization': 'Bearer <TOKEN>',
    'Content-Type': 'application/json',
    }

response = requests.request("PUT", url, data=payload, headers=headers)

print(response.text)
package main

import (
  "fmt"
  "strings"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/groups"

  payload := strings.NewReader("<REQUEST BODY>")

  req, _ := http.NewRequest("PUT", 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, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))

}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
   "Content-Type": "application/json",
]
let parameters = <REQUEST BODY> as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(
  url: NSURL(string: "http://rest.tsheets.com/api/v1/groups")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "PUT"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest,
  completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');
$client->addHeader('Content-Type', 'application/json');

$req = '<REQUEST BODY>';

$url="http://rest.tsheets.com/api/v1/groups"; 

$client->PUT($url, $req);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "groups": {
      "1": {
        "id": 6,
        "name": "Group 1a",
        "last_modified": "2018-08-19T16:29:28+00:00",
        "created": "2018-08-19T16:29:28+00:00",
        "manager_ids": []
      },
      "2": {
        "id": 8,
        "name": "Group 2b",
        "last_modified": "2018-08-19T16:29:35+00:00",
        "created": "2018-08-19T16:29:35+00:00",
        "manager_ids": [
          "316"
        ]
      }
    }
  },
  "more": false,
  "supplemental_data": {
    "users": {
      "316": {
        "id": 316,
        "first_name": "Bill",
        "last_name": "Franklin",
        "group_id": 0,
        "active": true,
        ...
      }
    }
  }
}

Edit one or more groups in your company.

HTTP Request

puthttps://rest.tsheets.com/api/v1/groups

Properties

Pass an array of group objects as the value to a 'data' property (see example).

id
required
Int Id of the group.

All other properties defined on a group object may be passed in to the request with a new value in order to change it. If the value passed in is the same as it was previously, or if a particular property is not passed in at all, it will be ignored.

Status Codes

Each group that is edited will come back with a _status_code and _status_message that will indicate whether the group was edited successfully. If there was a problem editing a group, there may also be an additional field, _status_extra, which will contain more details about the failure.

200 OK. Group was edited successfully.
417 Expectation Failed. Something was wrong or missing with the properties supplied for this group. See the _status_extra value for more detail.

Invitations

Create Invitations

Example: Invite two new users to the company.

Request Body

{
  "data": [
    {
      "contact_method": "email",
      "contact_info": "bobsmith@example.com",
      "user_id": "217432"
    },
    {
      "contact_method": "sms",
      "contact_info": "2085551234",
      "user_id": "217435"
    }
  ]
}

Request

curl -X POST \
  https://rest.tsheets.com/api/v1/invitations \
  -H 'Authorization: Bearer <TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '<REQUEST BODY>'
var client = new RestClient("https://rest.tsheets.com/api/v1/invitations");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <TOKEN>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "<REQUEST BODY>", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/invitations")
Dim request = New RestRequest(Method.POST)
request.AddHeader("Authorization", "Bearer <TOKEN>")
request.AddHeader("Content-Type", "application/json")
request.AddParameter("application/json", "<REQUEST BODY>", ParameterType.RequestBody);
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<REQUEST BODY>");
Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/invitations")
  .post(body)
  .addHeader("Authorization", "Bearer <TOKEN>")
  .addHeader("Content-Type", "application/json")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/groups?id=6%2C16&limit=30",
  "method": "POST",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
    "Content-Type", "application/json",
  },
  "processData": false,
  "data": "<REQUEST BODY>"
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'POST',
  url: 'https://rest.tsheets.com/api/v1/invitations',
  headers: 
  { 
     'Authorization': 'Bearer <TOKEN>',
     'Content-Type': 'application/json',
  },
  body: '<REQUEST BODY>',
  json: true };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/invitations');
$request->setMethod(HTTP_METH_POST);

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
  'Content-Type' => 'application/json',
));

$request->setBody('<REQUEST BODY>');

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/invitations")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <TOKEN>',
request["Content-Type"] = 'application/json',
request.body = "<REQUEST BODY>"

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/invitations"

payload = "<REQUEST BODY>"
headers = {
    'Authorization': 'Bearer <TOKEN>',
    'Content-Type': 'application/json',
    }

response = requests.request("POST", url, data=payload, headers=headers)

print(response.text)
package main

import (
  "fmt"
  "strings"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/invitations"

  payload := strings.NewReader("<REQUEST BODY>")

  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, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))

}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
   "Content-Type": "application/json",
]
let parameters = <REQUEST BODY> as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/invitations")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest,
  completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');
$client->addHeader('Content-Type', 'application/json');

$req = '<REQUEST BODY>';

$url="https://rest.tsheets.com/api/v1/invitations"; 

$client->POST($url, $req);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "invites": {
      "1": {
        "_status_code": 201,
        "_status_message": "Created"
      },
      "2": {
        "_status_code": 201,
        "_status_message": "Created"
      }
    }
  }
}

Invite one or more users to your company.

HTTP Request

posthttps://rest.tsheets.com/api/v1/invitations

Properties

Pass an array of invitation objects as the value to a 'data' property (see example).

contact_method
required
String Method to be used for the invitation, either 'sms' or 'email'
contact_info
required
String Email address or mobile phone number matching the type specified by the contact_method parameter.
user_id
required
Int Id of User object.

Status Codes

Each invitation that is created will come back with a _status_code and _status_message that will indicate whether the invitation was created successfully. If there was a problem creating an invitation, there may also be an additional field, _status_extra, which will contain more details about the failure.

201 Created. Invitation was created successfully.
400 Bad Request. See the _status_extra value for more detail.

Jobcodes

The Jobcode Object

Example

{
  "id": 17288279,
  "parent_id": 0,
  "assigned_to_all": false,
  "billable": false,
  "active": true,
  "type": "regular",
  "has_children": false,
  "billable_rate": 0,
  "short_code": "asm",
  "name": "Assembly Line",
  "last_modified": "2018-07-12T21:13:14+00:00",
  "created": "2018-05-28T20:18:17+00:00",
  "filtered_customfielditems": "",
  "required_customfields": [],
  "locations": [],
  "connect_with_quickbooks": true
}

Following is a list of the properties that belong to a jobcode object, and a description of each.

id
read-only
Int Id of jobcode.
parent_id
read-write
Int Id of this jobcode's parent. 0 if it's top-level.
name
read-write
String Name of the jobcode. Cannot be more than 64 characters and must be unique for all jobcodes that share the same parent_id.
short_code
read-write
String This is a shortened code or alias that is associated with the jobcode. It may only consist of letters and numbers. Must be unique for all jobcodes that share the same parent_id.
Note: If the Dial-in Add-on is installed, this field may only consist of numbers since it is used for jobcode selection from touch-tone phones.
type
read/write-once
String Indicates jobcode type. One of 'regular', 'pto', 'paid_break', or 'unpaid_break'. Additional types may be added in the future.
  • 'pto' type jobcodes are used for PTO (Paid Time Off, i.e. Vacation, Holiday) time entries. They are only allowed with a parent_id of 0 (i.e. top-level).
  • 'paid_break' and 'unpaid_break' type jobcodes are used in conjunction with the Breaks Add-On. These types of jobcodes may not be created/edited via the API. They are managed via the Breaks Add-On.
billable
read-write
Boolean true or false. Indicates whether this jobcode is billable or not.
billable_rate
read-write
Float Dollar amount associated with this jobcode for billing purposes. Only effective if billable is true.
has_children
read-only
Boolean true or false. If true, there are jobcodes that exist underneath this one, so this jobcode should be treated as a container or folder with children jobcodes underneath it.
assigned_to_all
read-write
Boolean true or false. Indicates whether this jobcode is assigned to all employees or not.
required_customfields
read-only
Array Ids of customfields that should be displayed when this jobcode is selected on a timecard.
filtered_customfielditems
read-only
Object Displays which customfielditems should be displayed when this jobcode is chosen for a timesheet. Each property of the object is a customfield id with its value being an array of customfielditem id. If none, an empty string is returned.
active
read-write
Boolean If true, this jobcode is active. If false, this jobcode is archived. To archive a jobcode, set this field to false. When a jobcode is archived, any children underneath the jobcode are archived as well. Note that when you archive a jobcode, any jobcode assignments or customfield dependencies are removed. To restore a jobcode, set this field to true. When a jobcode is restored, any parents of that jobcode are also restored.
last_modified
read-only
String Date/time when this jobcode was last modified, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm)
created
read-only
String Date/time when this jobcode was created, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm)
customfields
read-only
JSON Object A key/value map of customfield ids to the customfield items that are associated with the jobcode.

Note: this property is present only if the Custom Fields Add-On is installed, and the customfields query parameter is specified with a 'true' value.
connect_with_quickbooks
read-write
Boolean If true and the beta feature for two-way sync is enabled, then changes made to the jobcode are immediately shared with QBO.

Note: this property is present only if the beta two-way sync feature is enabled.

Retrieve Jobcodes

Example: Retrieve a list of all active top-level jobcodes.

Request

curl "https://rest.tsheets.com/api/v1/jobcodes" \
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/jobcodes");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/jobcodes")
Dim request = New RestRequest(Method.[GET])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/jobcodes")
  .get()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/jobcodes",
  "method": "GET",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'GET',
  url: 'https://rest.tsheets.com/api/v1/jobcodes',
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/jobcodes');
$request->setMethod(HTTP_METH_GET);

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/jobcodes")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/jobcodes"

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/jobcodes"

  req, _ := http.NewRequest("GET", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/jobcodes")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest, completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/jobcodes"; 

$client->GET($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Example: Retrieve a list of jobcodes with given ids.

Request

curl "https://rest.tsheets.com/api/v1/jobcodes?ids=12,367,3489" \
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/jobcodes?ids=12,367,3489");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/jobcodes?ids=12,367,3489")
Dim request = New RestRequest(Method.[GET])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/jobcodes?ids=12,367,3489")
  .get()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/jobcodes?ids=12,367,3489",
  "method": "GET",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'GET',
  url: 'https://rest.tsheets.com/api/v1/jobcodes',
  qs: {
    ids: '12,367,3489',
  },
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/jobcodes');
$request->setMethod(HTTP_METH_GET);

$request->setQueryData(array(
  'ids' => '12,367,3489',
));

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/jobcodes?ids=12,367,3489")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/jobcodes"

querystring = {
  "ids":"12,367,3489",
}

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/jobcodes?ids=12,367,3489"

  req, _ := http.NewRequest("GET", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/jobcodes?ids=12,367,3489")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest, completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/jobcodes?ids=12,367,3489"; 

$client->GET($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Example: Retrieve a list of jobcodes that have been modified since a particular date.

Request

curl "https://rest.tsheets.com/api/v1/jobcodes?modified_since=2018-01-01T00:00:00-0600" \
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/jobcodes?modified_since=2018-01-01T00:00:00-0600");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/jobcodes?modified_since=2018-01-01T00:00:00-0600")
Dim request = New RestRequest(Method.[GET])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/jobcodes?modified_since=2018-01-01T00:00:00-0600")
  .get()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/jobcodes?modified_since=2018-01-01T00:00:00-0600",
  "method": "GET",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'GET',
  url: 'https://rest.tsheets.com/api/v1/jobcodes',
  qs: {
    modified_since: '2018-01-01T00:00:00-0600',
  },
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/jobcodes');
$request->setMethod(HTTP_METH_GET);

$request->setQueryData(array(
  'modified_since' => '2018-01-01T00:00:00-0600',
));

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/jobcodes?modified_since=2018-01-01T00:00:00-0600")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/jobcodes"

querystring = {
  "modified_since":"2018-01-01T00:00:00-0600",
}

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/jobcodes?modified_since=2018-01-01T00:00:00-0600"

  req, _ := http.NewRequest("GET", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/jobcodes?modified_since=2018-01-01T00:00:00-0600")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest, completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/jobcodes?modified_since=2018-01-01T00:00:00-0600"; 

$client->GET($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
 "results": {
  "jobcodes": {
   "17288279": {
    "id": 17288279,
    "parent_id": 0,
    "assigned_to_all": false,
    "billable": false,
    "active": true,
    "type": "regular",
    "has_children": false,
    "billable_rate": 0,
    "short_code": "asm",
    "name": "Assembly Line",
    "last_modified": "2018-07-12T21:13:14+00:00",
    "created": "2018-05-28T20:18:17+00:00",
    "filtered_customfielditems": "",
    "required_customfields": [],
    "locations": [],
    "connect_with_quickbooks": true
   },
   "17288283": {
    "id": 17288283,
    "parent_id": 0,
    "assigned_to_all": false,
    "billable": false,
    "active": true,
    "type": "regular",
    "has_children": false,
    "billable_rate": 0,
    "short_code": "dev",
    "name": "Development Team",
    "last_modified": "2018-05-28T20:19:33+00:00",
    "created": "2018-05-28T20:19:33+00:00",
    "filtered_customfielditems": "",
    "required_customfields": [],
    "locations": [],
    "connect_with_quickbooks": false
   }
  }
 },
 "more": false
}

Example: Retrieve a list of all jobcodes (active or deleted) with given parent jobcode id. Set pagination to 10 results/page. Locations related to parent jobcodes will be returned with the supplemental data.

Request

curl "https://rest.tsheets.com/api/v1/jobcodes?parent_ids=235494&limit=10&active=both" \
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/jobcodes?parent_ids=235494&limit=10&active=both");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/jobcodes?parent_ids=235494&limit=10&active=both")
Dim request = New RestRequest(Method.[GET])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/jobcodes?parent_ids=235494&limit=10&active=both")
  .get()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/jobcodes?parent_ids=235494&limit=10&active=both",
  "method": "GET",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'GET',
  url: 'https://rest.tsheets.com/api/v1/jobcodes',
  qs: {
    parent_ids: '235494',
    limit: '10',
    active: 'both',
  },
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/jobcodes');
$request->setMethod(HTTP_METH_GET);

$request->setQueryData(array(
  'parent_ids' => '235494',
  'limit' => '10',
  'active' => 'both',
));

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/jobcodes?parent_ids=235494&limit=10&active=both")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/jobcodes"

querystring = {
  "parent_ids":"235494",
  "limit":"10",
  "active":"both",
}

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/jobcodes?parent_ids=235494&limit=10&active=both"

  req, _ := http.NewRequest("GET", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/jobcodes?parent_ids=235494&limit=10&active=both")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest, completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/jobcodes?parent_ids=235494&limit=10&active=both"; 

$client->GET($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
 "results": {
  "jobcodes": {
   "17973881": {
    "id": 17973881,
    "parent_id": 17288281,
    "assigned_to_all": false,
    "billable": false,
    "active": true,
    "type": "regular",
    "has_children": false,
    "billable_rate": 0,
    "short_code": "mop",
    "name": "Mopping",
    "last_modified": "2018-07-12T21:13:46+00:00",
    "created": "2018-07-12T21:13:46+00:00",
    "locations": [63534554, 635389373],
    "connect_with_quickbooks": true
   },
   "17973879": {
    "id": 17973879,
    "parent_id": 17288281,
    "assigned_to_all": false,
    "billable": false,
    "active": true,
    "type": "regular",
    "has_children": false,
    "billable_rate": 0,
    "short_code": "swp",
    "name": "Sweeping",
    "last_modified": "2018-07-12T21:13:38+00:00",
    "created": "2018-07-12T21:13:38+00:00",
    "locations": [635389373],
    "connect_with_quickbooks": false
   }
  }
 },
 "more": false,
 "supplemental_data": {
  "jobcodes": {
   "17288281": {
    "id": 17288281,
    "parent_id": 0,
    "assigned_to_all": false,
    "billable": false,
    "active": true,
    "type": "regular",
    "has_children": true,
    "billable_rate": 0,
    "short_code": "jan",
    "name": "Janatorial Work",
    "last_modified": "2018-07-12T21:13:02+00:00",
    "created": "2018-05-28T20:18:38+00:00",
    "locations": [63538272],
    "connect_with_quickbooks": true
   }
  },
  "locations": {
   "63534554": {
    "id": 63534554,
    "addr1": "5555 W Ridge Way",
    "addr2": "Suite 101",
    "city": "Boise",
    "state": "ID",
    "zip": 83702,
    "country": "US",
    "active": true,
    "latitude": 1.143,
    "longitude": -2.7346,
    "place_id": "ChIJrTLr-GyuEmsRBfy61i59si0",
    "label": "Home Office",
    "notes": "Key under the rug.",
    "last_modified": "2019-01-23T00:10:25+0000",
    "jobcodes": [17973881]
   },
   "635389373": {
    "id": 635389373,
    "addr1": "2544 E Summer Way",
    "addr2": "Suite 202",
    "city": "Boise",
    "state": "ID",
    "zip": 83703,
    "country": "US",
    "active": true,
    "latitude": 1.243,
    "longitude": -4.422,
    "place_id": "ChIJrTLr-GyuEmsRBfy61i584373",
    "label": "Work Office",
    "notes": "Use back door",
    "last_modified": "2019-01-23T00:10:25+0000",
    "jobcodes": [17973879]
   },
   "63538272": {
    "id": 63538272,
    "addr1": "1268 W River St",
    "addr2": "Suite 101",
    "city": "Boise",
    "state": "ID",
    "zip": 83702,
    "country": "US",
    "active": true,
    "latitude": 1.143,
    "longitude": -2.7346,
    "place_id": "ChIJrTLr-GyuEmsRBfy61i59si0",
    "label": "Home Office",
    "notes": "Key under the rug.",
    "last_modified": "2019-01-23T00:10:25+0000",
    "jobcodes": [17288281]
   }
  }
 }
}

Example: Retrieve a jobcode by id, including the customfields object in the response. The custom fields identified by id in the response object will be returned with the supplemental data.

Request

curl "https://rest.tsheets.com/api/v1/jobcodes?ids=11377903&customfields=true" \
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/jobcodes?ids=11377903&customfields=true");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/jobcodes?ids=11377903&customfields=true")
Dim request = New RestRequest(Method.[GET])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/jobcodes?ids=11377903&customfields=true")
  .get()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/jobcodes?ids=11377903&customfields=true",
  "method": "GET",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'GET',
  url: 'https://rest.tsheets.com/api/v1/jobcodes',
  qs: {
    ids: '11377903',
    customfields: 'true',
  },
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/jobcodes');
$request->setMethod(HTTP_METH_GET);

$request->setQueryData(array(
  'ids' => '11377903',
  'customfields' => 'true',
));

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/jobcodes?ids=11377903&customfields=true")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/jobcodes"

querystring = {
  "ids":"11377903",
  "customfields":"true",
}

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/jobcodes?ids=11377903&customfields=true"

  req, _ := http.NewRequest("GET", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/jobcodes?ids=11377903&customfields=true")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest, completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/jobcodes?ids=11377903&customfields=true"; 

$client->GET($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
    "results": {
        "jobcodes": {
            "11377903": {
                "id": 11377903,
                "parent_id": 0,
                "assigned_to_all": true,
                "billable": false,
                "active": true,
                "type": "regular",
                "has_children": false,
                "billable_rate": 0,
                "short_code": "",
                "name": "Idaho Construction",
                "last_modified": "2020-03-06T02:56:01+00:00",
                "created": "2019-09-03T16:34:20+00:00",
                "project_id": 0,
                "filtered_customfielditems": "",
                "required_customfields": [],
                "locations": [],
                "geofence_config_id": 0,
                "customfields": {
                    "6549432": "50.58",
                    "6549434": "433"
                },
                "connect_with_quickbooks": true
            }
        }
    },
    "more": false,
    "supplemental_data": {
        "customfields": {
            "6549432": {
                "id": 6549432,
                "active": true,
                "global": true,
                "required": false,
                "applies_to": "job_code",
                "type": "free-form",
                "short_code": "97343358",
                "regex_filter": "",
                "name": "Billable rate",
                "last_modified": "2020-03-10T22:11:36+00:00",
                "created": "2020-03-04T00:35:56+00:00",
                "ui_preference": "text_box_with_suggest",
                "required_customfields": []
            },
            "6549434": {
                "id": 6549434,
                "active": true,
                "global": true,
                "required": false,
                "applies_to": "job_code",
                "type": "free-form",
                "short_code": "73601320",
                "regex_filter": "",
                "name": "Department number",
                "last_modified": "2020-03-04T23:36:18+00:00",
                "created": "2020-03-04T00:37:02+00:00",
                "ui_preference": "text_box_with_suggest",
                "required_customfields": []
            }
        }
    }
}

Retrieves a list of all jobcodes associated with your company, with optional filters to narrow down the results. For a more efficient way of retrieving jobcodes assigned to a specific user, please see the Jobcode Assignments endpoint.

HTTP Request

gethttps://rest.tsheets.com/api/v1/jobcodes

Filter Parameters

ids
optional
Int Comma separated list of one or more jobcode ids you'd like to filter on. Only jobcodes with an id set to one of these values will be returned. If omitted, all jobcodes matching other specified filters are returned.
parent_ids
optional
Int Default is -1 (meaning all jobcodes will be returned regardless of parent_id).

Comma separated list of one or more jobcode parent_ids you'd like to filter on. Only jobcodes with a parent_id set to one of these values will be returned. Additionally you can use 0 to get only the top-level jobcodes. Then get the id of any results with has_children=yes and feed that in as the value of parent_ids for your next request to get the 2nd level of jobcodes, and so on, to traverse an entire tree of jobcodes.

Use -1 to return all jobcodes regardless of parent_id. This is especially useful when combined with the modified_since filter. When parent_ids is -1, you'll have the jobcode records needed to trace each result back to it's top level parent in the supplemental_data section of the response.
name
optional
String * will be interpreted as a wild card. Starts matching from the beginning of the string.
type
optional
String Indicates jobcode type. One of 'regular', 'pto', 'paid_break', 'unpaid_break', or 'all'. Default is 'regular'.
active
optional
String 'yes', 'no', or 'both'. Default is 'yes'. If a jobcode is active, it is available for selection during time entry.
customfields
optional
Boolean true or false. If true, custom fields for this jobcode will be returned. If false, the customfields object will be omitted.
modified_before
optional
String Only jobcodes modified before this date/time will be returned, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm).
modified_since
optional
String Only jobcodes modified since this date/time will be returned, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm).
supplemental_data
optional
String 'yes' or 'no'. Default is 'yes'. Indicates whether supplemental data should be returned.
per_page
optional
Int Deprecated. Use limit for new code.
Represents how many results you'd like to retrieve per request. Default is 50. Max is 50.
If a value over 50 is provided, it is ignored, and the max is used.
limit
optional
Int Represents how many results you'd like to retrieve per request. Default is 200. Max is 200.
If present, this value must be: an integer, greater than zero, and not greater than 200.
Setting limit less than 1 or greater than 200 will result in an error.
page
optional
Int Represents the page of results you'd like to retrieve. Default is 1.

Create Jobcodes

Example: Create two new jobcodes. One succeeds. The other fails because of a duplicate short_code on an existing jobcode.

Request Body

{
 "data":
  [
    {
     "name":"Customer1",
     "parent_id":"12788279",
     "short_code":"c1",
     "billable":"yes",
     "assigned_to_all":"yes",
     "billable_rate":"37.50",
     "connect_with_quickbooks":true
    },
    {
     "name":"Customer2",
     "parent_id":"12788279",
     "short_code":"c1",
     "billable":"no",
     "assigned_to_all":"no",
     "billable_rate":"37.50",
     "connect_with_quickbooks":false
    }
  ]
}


Request

curl -X POST \
  https://rest.tsheets.com/api/v1/jobcodes \
  -H 'Authorization: Bearer <TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '<REQUEST BODY>'
var client = new RestClient("https://rest.tsheets.com/api/v1/jobcodes");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <TOKEN>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "<REQUEST BODY>", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/jobcodes")
Dim request = New RestRequest(Method.POST)
request.AddHeader("Authorization", "Bearer <TOKEN>")
request.AddHeader("Content-Type", "application/json")
request.AddParameter("application/json", "<REQUEST BODY>", ParameterType.RequestBody);
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<REQUEST BODY>");
Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/jobcodes")
  .post(body)
  .addHeader("Authorization", "Bearer <TOKEN>")
  .addHeader("Content-Type", "application/json")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/jobcodes?ids=11377903&customfields=true",
  "method": "POST",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
    "Content-Type", "application/json",
  },
  "processData": false,
  "data": "<REQUEST BODY>"
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'POST',
  url: 'https://rest.tsheets.com/api/v1/jobcodes',
  headers: 
  { 
     'Authorization': 'Bearer <TOKEN>',
     'Content-Type': 'application/json',
  },
  body: '<REQUEST BODY>',
  json: true };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/jobcodes');
$request->setMethod(HTTP_METH_POST);

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
  'Content-Type' => 'application/json',
));

$request->setBody('<REQUEST BODY>');

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/jobcodes")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <TOKEN>',
request["Content-Type"] = 'application/json',
request.body = "<REQUEST BODY>"

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/jobcodes"

payload = "<REQUEST BODY>"
headers = {
    'Authorization': 'Bearer <TOKEN>',
    'Content-Type': 'application/json',
    }

response = requests.request("POST", url, data=payload, headers=headers)

print(response.text)
package main

import (
  "fmt"
  "strings"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/jobcodes"

  payload := strings.NewReader("<REQUEST BODY>")

  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, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))

}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
   "Content-Type": "application/json",
]
let parameters = <REQUEST BODY> as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/jobcodes")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest,
  completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');
$client->addHeader('Content-Type', 'application/json');

$req = '<REQUEST BODY>';

$url="https://rest.tsheets.com/api/v1/jobcodes"; 

$client->POST($url, $req);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "jobcodes": {
      "1": {
        "_status_code": 200,
        "_status_message": "Created",
        "id": 18059008,
        "parent_id": 17288279,
        "assigned_to_all": true,
        "billable": true,
        "active": true,
        "type": "regular",
        "has_children": false,
        "billable_rate": 37.5,
        "short_code": "c1",
        "name": "Customer1",
        "last_modified": "2018-07-22T19:19:28+00:00",
        "created": "2018-07-22T19:19:28+00:00",
        "required_customfields": [],
        "filtered_customfielditems": "",
        "connect_with_quickbooks": true
      },
      "2": {
        "_status_code": 417,
        "_status_message": "Expectation Failed",
        "_status_extra": "Oops! That Short Code is already in use",
        "name": "Customer2"
      }
    }
  },
  "supplemental_data": {
    "jobcodes": {
      "17288279": {
        "id": 17288279,
        "parent_id": 0,
        "assigned_to_all": false,
        "billable": false,
        "active": true,
        "type": "regular",
        "has_children": true,
        "billable_rate": 0,
        "short_code": "asm",
        "name": "Assembly Line",
        "last_modified": "2018-07-12T21:13:14+00:00",
        "created": "2018-05-28T20:18:17+00:00",
        "required_customfields": [],
        "filtered_customfielditems": "",
        "connect_with_quickbooks": true
      }
    }
  }
}

Add one or more jobcodes to your company.

HTTP Request

posthttps://rest.tsheets.com/api/v1/jobcodes

Properties

Pass an array of jobcode objects as the value to a 'data' property (see example).

name
required
String Name of the jobcode.

For a full list of the properties that may be set on a jobcode, see the Jobcode object.

Status Codes

Each jobcode that is created will come back with a _status_code and _status_message that will indicate whether the jobcode was created successfully. If there was a problem creating a jobcode, there may also be an additional field, _status_extra, which will contain more details about the failure.

200 OK. Jobcode was created successfully.
202 OK. Jobcode accepted but not created because a jobcode with the same parent_id, name and type already exists.
417 Expectation Failed. Something was wrong or missing with the properties supplied for this jobcode. See the _status_extra value for more detail.

Update Jobcodes

Example: Change some information for each of these jobcodes.

Request Body

{
  "data":
  [
    {
      "id": 10606354,
      "short_code": "cc3",
      "billable": "false",
      "name": "Customer30",
      "billable_rate": "57.50",
      "connect_with_quickbooks": true
    },
    {
      "id": 10608414,
      "short_code": "cc4",
      "billable": "false",
      "name": "Customer40",
      "billable_rate": "57.50",
      "connect_with_quickbooks": true
    },
    {
      "id": 10608424,
      "short_code": "cc1",
      "billable": "false",
      "name": "Customer10",
      "billable_rate": "57.50",
      "connect_with_quickbooks": false
    }
  ]
}

Request

curl -X PUT \
  https://rest.tsheets.com/api/v1/jobcodes \
  -H 'Authorization: Bearer <TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '<REQUEST BODY>'
var client = new RestClient("https://rest.tsheets.com/api/v1/jobcodes");
var request = new RestRequest(Method.PUT);
request.AddHeader("Authorization", "Bearer <TOKEN>");
request.AddHeader("Content-Type", "application/json");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/jobcodes")
Dim request = New RestRequest(Method.PUT)
request.AddHeader("Authorization", "Bearer <TOKEN>")
request.AddHeader("Content-Type", "application/json")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<REQUEST BODY>");
Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/jobcodes")
  .put(body)
  .addHeader("Authorization", "Bearer <TOKEN>")
  .addHeader("Content-Type", "application/json")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/jobcodes?ids=11377903&customfields=true",
  "method": "PUT",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
    "Content-Type", "application/json",
  },
  "processData": false,
  "data": "<REQUEST BODY>"
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'PUT',
  url: 'https://rest.tsheets.com/api/v1/jobcodes',
  headers: 
  { 
     'Authorization': 'Bearer <TOKEN>',
     'Content-Type': 'application/json',
  },
  body: '<REQUEST BODY>',
  json: true };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/jobcodes');
$request->setMethod(HTTP_METH_PUT);

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
  'Content-Type' => 'application/json',
));

$request->setBody('<REQUEST BODY>');

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/jobcodes")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <TOKEN>',
request["Content-Type"] = 'application/json',
request.body = "<REQUEST BODY>"

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/jobcodes"

payload = "<REQUEST BODY>"
headers = {
    'Authorization': 'Bearer <TOKEN>',
    'Content-Type': 'application/json',
    }

response = requests.request("PUT", url, data=payload, headers=headers)

print(response.text)
package main

import (
  "fmt"
  "strings"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/jobcodes"

  payload := strings.NewReader("<REQUEST BODY>")

  req, _ := http.NewRequest("PUT", 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, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))

}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
   "Content-Type": "application/json",
]
let parameters = <REQUEST BODY> as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(
  url: NSURL(string: "http://rest.tsheets.com/api/v1/jobcodes")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "PUT"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest,
  completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');
$client->addHeader('Content-Type', 'application/json');

$req = '<REQUEST BODY>';

$url="http://rest.tsheets.com/api/v1/jobcodes"; 

$client->PUT($url, $req);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "jobcodes": {
      "1": {
        "_status_code": 200,
        "_status_message": "Updated",
        "id": 18059008,
        "parent_id": 17288279,
        "assigned_to_all": true,
        "billable": false,
        "active": true,
        "type": "regular",
        "has_children": false,
        "billable_rate": 57.5,
        "short_code": "cc3",
        "name": "Customer30",
        "connect_with_quickbooks": true,
        "last_modified": "2018-07-22T22:12:04+00:00",
        "created": "2018-07-22T19:19:28+00:00"
      },
      "2": {
        "_status_code": 200,
        "_status_message": "Updated",
        "id": 18064850,
        "parent_id": 17288279,
        "assigned_to_all": false,
        "billable": false,
        "active": true,
        "type": "regular",
        "has_children": false,
        "billable_rate": 57.5,
        "short_code": "cc4",
        "name": "Customer40",
        "connect_with_quickbooks": true,
        "last_modified": "2018-07-22T22:12:05+00:00",
        "created": "2018-07-22T21:20:43+00:00"
      },
      "3": {
        "_status_code": 200,
        "_status_message": "Updated",
        "id": 18064852,
        "parent_id": 17288279,
        "assigned_to_all": false,
        "billable": false,
        "active": true,
        "type": "regular",
        "has_children": false,
        "billable_rate": 57.5,
        "short_code": "cc1",
        "name": "Customer10",
        "connect_with_quickbooks": false,
        "last_modified": "2018-07-22T22:12:06+00:00",
        "created": "2018-07-22T21:20:51+00:00"
      }
    }
  },
  "supplemental_data": {
    "jobcodes": {
      "17288279": {
        "id": 17288279,
        "parent_id": 0,
        "assigned_to_all": false,
        "billable": false,
        "active": true,
        "type": "regular",
        "has_children": true,
        "billable_rate": 0,
        "short_code": "asm",
        "name": "Assembly Line",
        "connect_with_quickbooks": true,
        "last_modified": "2018-07-12T21:13:14+00:00",
        "created": "2018-05-28T20:18:17+00:00"
      }
    }
  }
}


Edit one or more jobcodes in your company.

HTTP Request

puthttps://rest.tsheets.com/api/v1/jobcodes

Properties

Pass an array of jobcode objects as the value to a 'data' property (see example).

id
required
Int Id of the jobcode.

Other properties defined on a jobcode object may be passed in to the request with a new value in order to change it. If the value passed in is the same as it was previously, or if a particular property is not passed in at all, it will be ignored.

Status Codes

Each jobcode that is edited will come back with a _status_code and _status_message that will indicate whether the jobcode was edited successfully. If there was a problem editing a jobcode, there may also be an additional field, _status_extra, which will contain more details about the failure.

200 OK. Jobcode was edited successfully.
417 Expectation Failed. Something was wrong or missing with the properties supplied for this jobcode. See the _status_extra value for more detail.

Jobcode Assignments

A jobcode assignment represents that a user has access to a given jobcode for selection while tracking time. A jobcode is considered assigned if the jobcode has been specifically assigned to a person, or if the jobcode has the assigned_to_allproperty set to true.

The Jobcode Assignments Object

Example

{
  "id": 26881275,
  "user_id": 1242515,
  "jobcode_id": 17285791,
  "active": true,
  "last_modified": "",
  "created": ""
}

Following is a list of the properties that belong to a jobcode assignment object, and a description of each.

id
read-only
Int Id of jobcode assignment.
user_id
read-write
Int Id of the user that this assignment pertains to.
jobcode_id
read-write
Int Id of the jobcode that this assignment pertains to.
active
read-write
Boolean true or false. Whether or not this assignment is 'active'. If false, then the assignment has been deleted. true means it is in force.
last_modified
read-only
String Date/time when this jobcode assignment was last modified, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm)
created
read-only
String Date/time when this jobcode assignment was created, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm)

Retrieve Jobcode Assignments

Example: Retrieve a list of all jobcode assignments for a given user_id.

Request

curl "https://rest.tsheets.com/api/v1/jobcode_assignments?user_ids=1242515" \
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/jobcode_assignments?user_ids=1242515");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/jobcode_assignments?user_ids=1242515")
Dim request = New RestRequest(Method.[GET])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/jobcode_assignments?user_ids=1242515")
  .get()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/jobcode_assignments?user_ids=1242515",
  "method": "GET",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'GET',
  url: 'https://rest.tsheets.com/api/v1/jobcode_assignments',
  qs: {
    user_ids: '1242515',
  },
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/jobcode_assignments');
$request->setMethod(HTTP_METH_GET);

$request->setQueryData(array(
  'user_ids' => '1242515',
));

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/jobcode_assignments?user_ids=1242515")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/jobcode_assignments"

querystring = {
  "user_ids":"1242515",
}

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/jobcode_assignments?user_ids=1242515"

  req, _ := http.NewRequest("GET", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/jobcode_assignments?user_ids=1242515")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest, completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/jobcode_assignments?user_ids=1242515"; 

$client->GET($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "jobcode_assignments": {
      "26881275": {
        "id": 26881275,
        "user_id": 1242515,
        "jobcode_id": 17285791,
        "active": true,
        "last_modified": "",
        "created": ""
      },
      "26881277": {
        "id": 26881277,
        "user_id": 1242515,
        "jobcode_id": 17285793,
        "active": true,
        "last_modified": "",
        "created": ""
      },
      "26881273": {
        "id": 26881273,
        "user_id": 1242515,
        "jobcode_id": 17285795,
        "active": true,
        "last_modified": "",
        "created": ""
      },
      "26881271": {
        "id": 26881271,
        "user_id": 1242515,
        "jobcode_id": 17288283,
        "active": true,
        "last_modified": "",
        "created": ""
      }
    }
  },
  "more": false,
  "supplemental_data": {
    "users": {
      "1242515": {
        "id": 1242515,
        "first_name": "Alexander",
        "last_name": "Luzzana",
        "group_id": 144959,
        "active": true,
        ...
      }
    },
    "jobcodes": {
      "17285791": {
        "id": 17285791,
        "parent_id": 0,
        "assigned_to_all": true,
        "billable": false,
        "active": true,
        "type": "pto",
        ...
      },
      "17285793": {
        "id": 17285793,
        "parent_id": 0,
        "assigned_to_all": true,
        "billable": false,
        "active": true,
        "type": "pto",
        ...
      },
      "17285795": {
        "id": 17285795,
        "parent_id": 0,
        "assigned_to_all": true,
        "billable": false,
        "active": true,
        "type": "pto",
        ...
      },
      "17288283": {
        "id": 17288283,
        "parent_id": 0,
        "assigned_to_all": false,
        "billable": false,
        "active": true,
        "type": "regular",
        ...
      }
    }
  }
}

Example: Retrieve a list of all jobcode assignments modified since a particular date. Set pagination to 10 results/page. Currently logged in user's id will be used, since none is specified in the request.

Request

curl "https://rest.tsheets.com/api/v1/jobcode_assignments?modified_since=2018-03-01T00:00:00-0600&limit=10" \
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/jobcode_assignments?modified_since=2018-03-01T00:00:00-0600&limit=10");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/jobcode_assignments?modified_since=2018-03-01T00:00:00-0600&limit=10")
Dim request = New RestRequest(Method.[GET])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/jobcode_assignments?modified_since=2018-03-01T00:00:00-0600&limit=10")
  .get()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/jobcode_assignments?modified_since=2018-03-01T00:00:00-0600&limit=10",
  "method": "GET",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'GET',
  url: 'https://rest.tsheets.com/api/v1/jobcode_assignments',
  qs: {
    modified_since: '2018-03-01T00:00:00-0600',
    limit: '10',
  },
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/jobcode_assignments');
$request->setMethod(HTTP_METH_GET);

$request->setQueryData(array(
  'modified_since' => '2018-03-01T00:00:00-0600',
  'limit' => '10',
));

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/jobcode_assignments?modified_since=2018-03-01T00:00:00-0600&limit=10")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/jobcode_assignments"

querystring = {
  "modified_since":"2018-03-01T00:00:00-0600",
  "limit":"10",
}

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/jobcode_assignments?modified_since=2018-03-01T00:00:00-0600&limit=10"

  req, _ := http.NewRequest("GET", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/jobcode_assignments?modified_since=2018-03-01T00:00:00-0600&limit=10")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest, completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/jobcode_assignments?modified_since=2018-03-01T00:00:00-0600&limit=10"; 

$client->GET($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "jobcode_assignments": {
      "27569720": {
        "id": 27569720,
        "user_id": 0,
        "jobcode_id": 18081060,
        "active": true,
        "last_modified": "2018-07-24T18:18:37+00:00",
        "created": "2018-07-24T18:18:37+00:00"
      }
    }
  },
  "more": false,
  "supplemental_data": {
    "jobcodes": {
      "18081060": {
        "id": 18081060,
        "parent_id": 0,
        "assigned_to_all": true,
        "billable": false,
        "active": true,
        "type": "regular",
        "has_children": false,
        "billable_rate": 0,
        "short_code": "test",
        "name": "Test",
        "last_modified": "2018-07-24T18:18:36+00:00",
        "created": "2018-07-23T22:41:02+00:00",
        "locations": []
      }
    }
  }
}

Retrieves a list of all jobcode assignments associated with users, with optional filters to narrow down the results. Note that jobcodes with the property assigned_to_all set to true will always be considered assigned to any given user. assigned_to_all jobcode assignments are indicated by a user_id value of 0 in the results. Also note that only active jobcodes will be considered assigned, as once a jobcode is archived, it is no longer available for selection for time entry.

HTTP Request

gethttps://rest.tsheets.com/api/v1/jobcode_assignments

Filter Parameters

user_ids
optional
Int Comma separated string of one or more user ids for whom you'd like to retrieve jobcode assignments. If none are specified, all jobcode assignments (which you have rights to view) will be returned. Only jobcode assignments belonging to these user_ids or where the jobcode assigned_to_all property is true will be returned. Results where assigned_to_all is true for a jobcode are indicated by a user_id value of 0 for the jobcode_assignment object. To view jobcode assignments for users other than yourself you must be an admin or a group manager or have the manage_users permission or the manage_jobcodes permission.
type
optional
String Refers to the jobcode type - 'regular', 'pto', 'unpaid_break', 'paid_break', or 'all'. Defaults to 'regular'.
jobcode_id
optional
Int If specified, only assignments for jobcodes with the given id are returned.
jobcode_parent_id
optional
Int When omitted, all jobcode assignments are returned regardless of jobcode parent. If specified, only assignments for jobcodes with the given jobcode parent_id are returned. To get a list of only top-level jobcode assignments, pass in a jobcode_parent_id of 0.
active
optional
String 'yes', 'no, or 'both'. Default is 'both'. 'yes' means the assignment is active, 'no' means it is deleted/inactive.
active_jobcodes
optional
String 'yes', 'no, or 'both'. Default is 'both'. 'yes' means only assignments where the jobcode is active, 'no' means only assignments where jobcodes are inactive.
modified_before
optional
String Only jobcode assignments modified before this date/time will be returned, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm).
modified_since
optional
String Only jobcode assignments modified since this date/time will be returned, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm).
supplemental_data
optional
String 'yes' or 'no'. Default is 'yes'. Indicates whether supplemental data should be returned.
per_page
optional
Int Deprecated. Use limit for new code.
Represents how many results you'd like to retrieve per request. Default is 50. Max is 50.
If a value over 50 is provided, it is ignored, and the max is used.
limit
optional
Int Represents how many results you'd like to retrieve per request. Default is 200. Max is 200.
If present, this value must be: an integer, greater than zero, and not greater than 200.
Setting limit less than 1 or greater than 200 will result in an error.
page
optional
Int Represents the page of results you'd like to retrieve. Default is 1.

Create Jobcode Assignments

Example: Create two new jobcode assignments. One succeeds. The other fails because of a permissions issue with the user_id.

Request Body

{
  "data":
  [
    {
      "user_id":"1234",
      "jobcode_id":"37"
    },
    {
      "user_id":"4567",
      "jobcode_id":"37"
    }
  ]
}

Request

curl -X POST \
  https://rest.tsheets.com/api/v1/jobcode_assignments \
  -H 'Authorization: Bearer <TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '<REQUEST BODY>'
var client = new RestClient("https://rest.tsheets.com/api/v1/jobcode_assignments");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <TOKEN>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "<REQUEST BODY>", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/jobcode_assignments")
Dim request = New RestRequest(Method.POST)
request.AddHeader("Authorization", "Bearer <TOKEN>")
request.AddHeader("Content-Type", "application/json")
request.AddParameter("application/json", "<REQUEST BODY>", ParameterType.RequestBody);
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<REQUEST BODY>");
Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/jobcode_assignments")
  .post(body)
  .addHeader("Authorization", "Bearer <TOKEN>")
  .addHeader("Content-Type", "application/json")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/jobcode_assignments?modified_since=2018-03-01T00:00:00-0600&limit=10",
  "method": "POST",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
    "Content-Type", "application/json",
  },
  "processData": false,
  "data": "<REQUEST BODY>"
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'POST',
  url: 'https://rest.tsheets.com/api/v1/jobcode_assignments',
  headers: 
  { 
     'Authorization': 'Bearer <TOKEN>',
     'Content-Type': 'application/json',
  },
  body: '<REQUEST BODY>',
  json: true };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/jobcode_assignments');
$request->setMethod(HTTP_METH_POST);

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
  'Content-Type' => 'application/json',
));

$request->setBody('<REQUEST BODY>');

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/jobcode_assignments")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <TOKEN>',
request["Content-Type"] = 'application/json',
request.body = "<REQUEST BODY>"

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/jobcode_assignments"

payload = "<REQUEST BODY>"
headers = {
    'Authorization': 'Bearer <TOKEN>',
    'Content-Type': 'application/json',
    }

response = requests.request("POST", url, data=payload, headers=headers)

print(response.text)
package main

import (
  "fmt"
  "strings"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/jobcode_assignments"

  payload := strings.NewReader("<REQUEST BODY>")

  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, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))

}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
   "Content-Type": "application/json",
]
let parameters = <REQUEST BODY> as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/jobcode_assignments")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest,
  completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');
$client->addHeader('Content-Type', 'application/json');

$req = '<REQUEST BODY>';

$url="https://rest.tsheets.com/api/v1/jobcode_assignments"; 

$client->POST($url, $req);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "jobcode_assignments": {
      "1": {
        "_status_code": 200,
        "_status_message": "Created",
        "id": 106063,
        "user_id": "1234",
        "jobcode_id": "37",
        "last_modified": "2018-01-17 21:15:18",
        "created": "2018-01-17 21:15:18"
      },
      "2": {
        "_status_code": 417,
        "_status_message": "Expectation Failed",
        "_status_extra": "Oops! You don't have permission to manage that user",
        "user_id": "4567",
        "jobcode_id": "37"
      }
    }
  },
  "supplemental_data": {
    "users": {
      "1234": {
        "id": "1234",
        "first_name": "John",
        "last_name": "Smith",
        "group_id": "983247",
        "active": 1,
        ...
      }
    },
    "jobcodes": {
      "37": {
        "id": 37,
        "parent_id": 0,
        "assigned_to_all": "",
        "billable": "",
        "active": 1,
        ...
      }
    }
  }
}

Add one or more jobcode assignments to a user.

HTTP Request

posthttps://rest.tsheets.com/api/v1/jobcode_assignments

Properties

Pass an array of jobcode assignment objects as the value to a 'data' property (see example).

user_id
required
Int User id for this jobcode assignment.
Note: Specify a user_id of 0 to indicate that this jobcode_assignment should apply to all users. This is equivalent to setting the assigned_to_all property to true on a jobcode object.
jobcode_id
required
Int Jobcode id for this jobcode assignment.

Status Codes

Each jobcode assignment that is created will come back with a _status_code and _status_message that will indicate whether the jobcode assignment was created successfully. If there was a problem creating a jobcode assignment, there may also be an additional field, _status_extra, which will contain more details about the failure.

200 OK. Jobcode assignment was created successfully.
417 Expectation Failed. Something was wrong or missing with the properties supplied for this jobcode assignment. See the _status_extra value for more detail.

Delete Jobcode Assignments

Example: Request to delete four jobcode assignments. Two succeed and two result in error.

Request

curl -X DELETE "https://rest.tsheets.com/api/v1/jobcode_assignments?ids=56788052,58078296,,1234"
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/jobcode_assignments?ids=56788052,58078296,,1234");
var request = new RestRequest(Method.DELETE);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/jobcode_assignments?ids=56788052,58078296,,1234")
Dim request = New RestRequest(Method.[DELETE])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/jobcode_assignments?ids=56788052,58078296,,1234")
  .delete()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/jobcode_assignments?ids=56788052,58078296,,1234",
  "method": "DELETE",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'DELETE',
  url: 'https://rest.tsheets.com/api/v1/jobcode_assignments',
  qs: {
    ids: '56788052,58078296,,1234',
  },
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/jobcode_assignments');
$request->setMethod(HTTP_METH_DELETE);

$request->setQueryData(array(
  'ids' => '56788052,58078296,,1234',
));

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/jobcode_assignments?ids=56788052,58078296,,1234")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Delete.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/jobcode_assignments"

querystring = {
  "ids":"56788052,58078296,,1234",
}

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/jobcode_assignments?ids=56788052,58078296,,1234"

  req, _ := http.NewRequest("DELETE", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/jobcode_assignments?ids=56788052,58078296,,1234")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "DELETE"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/jobcode_assignments?ids=56788052,58078296,,1234"; 

$client->DELETE($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "jobcode_assignments": {
      "56788052": {
        "_status_code": 200,
        "_status_message": "OK, deleted",
        "id": 56788052,
      },
      "58078296": {
        "_status_code": 200,
        "_status_message": "OK, deleted",
        "id": 58078296,
      },
      "": {
        "_status_code": 417,
        "_status_message": "Expectation Failed!",
        "_status_extra": "That id is not found in the database",
        "id": "",
      },
      "1234": {
        "_status_code": 417,
        "_status_message": "Expectation Failed!",
        "_status_extra": "Oops! You don't have permission to remove jobcodes for that user.",
        "id": "1234",
      }
    }
  }
}

Delete one or more jobcode assignments for a user.

HTTP Request

deletehttps://rest.tsheets.com/api/v1/jobcode_assignments

Parameters

If no filters are specified at all, no jobcode assignments are deleted.

ids
optional
String Comma separated list of jobcode assignment ids you'd like to delete.

Status Codes

Each jobcode assignment that is deleted will come back with a _status_code and _status_message that will indicate whether the jobcode assignment was deleted successfully. If there was a problem deleting a jobcode assignment, there may also be an additional field, _status_extra, which will contain more details about the failure.

200 OK. Jobcode assignment was deleted successfully.
417 Expectation Failed. Something went wrong for this jobcode assignment. See the _status_extra value for more detail.

Last Modified Timestamps

This object contains the most recent modification timestamp for objects from each requested API endpoint.

The object consists of a name of each requested endpoint and a corresponding timestamp. Each timestamp represents the most recent time that a change was made to one of the objects tied to its respective API endpoint. This is especially useful because you can see with just one request what endpoints may need to be queried to get changes since the last time you connected to the API.

See the List documentation for example output.

Retrieve Last Modified Timestamps

Example: Retrieve the default list of last modified timestamps.

Request

curl "https://rest.tsheets.com/api/v1/last_modified_timestamps" \
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/last_modified_timestamps");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/last_modified_timestamps")
Dim request = New RestRequest(Method.[GET])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/last_modified_timestamps")
  .get()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/last_modified_timestamps",
  "method": "GET",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'GET',
  url: 'https://rest.tsheets.com/api/v1/last_modified_timestamps',
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/last_modified_timestamps');
$request->setMethod(HTTP_METH_GET);

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/last_modified_timestamps")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/last_modified_timestamps"

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/last_modified_timestamps"

  req, _ := http.NewRequest("GET", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/last_modified_timestamps")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest, completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/last_modified_timestamps"; 

$client->GET($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "last_modified_timestamps": {
      "current_user": "2018-03-28T17:24:20+00:00",
      "customfields": "2018-04-05T19:47:19+00:00",
      "customfielditems": "2018-04-04T16:10:44+00:00",
      "effective_settings": "2018-04-05T19:47:19+00:00",
      "geolocations": "2018-03-27T16:13:28+00:00",
      "jobcodes": "2018-04-05T19:47:19+00:00",
      "jobcode_assignments": "2018-04-05T19:47:19+00:00",
      "timesheets": "2018-03-28T20:16:39+00:00",
      "timesheets_deleted": "2018-03-27T16:13:28+00:00",
      "users": "2018-04-05T19:47:18+00:00",
      "reminders": "2018-03-27T16:13:29+00:00",
      "locations": "2018-07-16T23:36:27+00:00",
      "geofence_configs": "2018-05-20T12:34:56+00:00"
    }
  }
}

Example: Retrieve the last modified timestamps for 'timesheets' and 'groups'.

Request

curl "https://rest.tsheets.com/api/v1/last_modified_timestamps?endpoints=timesheets,groups" \
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/last_modified_timestamps?endpoints=timesheets,groups");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/last_modified_timestamps?endpoints=timesheets,groups")
Dim request = New RestRequest(Method.[GET])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/last_modified_timestamps?endpoints=timesheets,groups")
  .get()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/last_modified_timestamps?endpoints=timesheets,groups",
  "method": "GET",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'GET',
  url: 'https://rest.tsheets.com/api/v1/last_modified_timestamps',
  qs: {
    endpoints: 'timesheets,groups',
  },
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/last_modified_timestamps');
$request->setMethod(HTTP_METH_GET);

$request->setQueryData(array(
  'endpoints' => 'timesheets,groups',
));

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/last_modified_timestamps?endpoints=timesheets,groups")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/last_modified_timestamps"

querystring = {
  "endpoints":"timesheets,groups",
}

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/last_modified_timestamps?endpoints=timesheets,groups"

  req, _ := http.NewRequest("GET", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/last_modified_timestamps?endpoints=timesheets,groups")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest, completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/last_modified_timestamps?endpoints=timesheets,groups"; 

$client->GET($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
 "results": {
  "last_modified_timestamps": {
   "timesheets": "2018-03-28T20:16:39+00:00",
   "groups": "2018-03-27T16:13:30+00:00"
  }
 }
}

Retrieves a list of last_modified timestamps associated with each requested API endpoint. This is especially useful because you can see, with just one request, what endpoints may need to be queried to get changes since the last time you connected to the API.

HTTP Request

gethttps://rest.tsheets.com/api/v1/last_modified_timestamps

Filter Parameters

endpoints
optional
String Comma separated list of one or more endpoints. You can specify any endpoint - see each respective endpoint for the endpoint 'name' that you can use in this list. E.g. if you wanted to only check for changed timesheets and jobcodes, you'd specify 'timesheets,timesheets_deleted,jobcodes' as the value of this filter.

If a list of endpoints is not specified, then the following list is returned by default.:
  • current_user
  • customfields
  • customfielditems
  • effective_settings
  • geolocations
  • jobcodes
  • jobcode_assignments
  • timesheets
  • timesheets_deleted
  • users
  • reminders
  • locations
  • geofence_configs

Locations

The Location Object

Example

{
  "id": 65305,
  "addr1": "235 E Colchester Dr",
  "addr2": "101",
  "city": "Eagle",
  "state": "ID",
  "zip": "83616",
  "country": "US",
  "formatted_address": "235 E Colchester Dr 101, Eagle, ID 83616",
  "active": true,
  "latitude": 43.6700273,
  "longitude": -116.3520972,
  "place_id": "",
  "place_id_hash": "0ba5eaf96c5f63c3b76d5084c365b6e4",
  "label": "TSheets, East Colchester Drive, Eagle, ID, USA",
  "notes": "",
  "geocoding_status": "complete",
  "created": "2018-03-09T18:26:57+00:00",
  "last_modified": "2018-03-15T16:51:14+00:00",
  "linked_objects": {
    "jobcodes": [
      2589531
    ]
  },
  "geofence_config_id": null
}

Following is a list of the properties that belong to a location object, and a description of each.

id
read-only
Int Id of location.
addr1
read-write
String The first line of the location's address
addr2
read-write
String The second line of the location's address
city
read-write
String The city of the location's address.
state
read-write
String The state of the location's address
zip
read-write
String The postal code of the location's address
country
read-write
String The country of the location's address
formatted_address
read-only
String Formatted address built from the objects addr1, addr2, city, state, and zip. If the location doesn't contain addr1, addr2, or city properties, the value will default what is set in the label property.
active
read-write
Boolean If true, this location is active. If false, this location is archived.
latitude
read-write
Float The latitude of the location (in signed degrees format).
longitude
read-write
Float The longitude of the location (in signed degrees format).
place_id_hash
read-only
String The MD5 hash of the unique id for the location returned from the geocoding service.
label
read-only
String The formated name for the location. If the location was found using the geocode service the formated address will be saved in this field, otherwise it will be what the user has named the location.
notes
read-write
String Notes related to the location.
geocoding_status
read-only
String The geocoding status of this address. Will be one of: 'none', 'in_progress', 'retry', 'error', or 'complete'.
last_modified
read-only
String Date/time when this location was last modified, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm)
created
read-only
String Date/time when this location was created, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm)
linked_objects
read-write
Object A key/value map of all the objects linked to this location and the corresponding object ids.
geofence_config_id
read-only
Int Id of the geofence_config associated with this location.

Retrieve Locations

Example: Retrieve a list of all active locations.

Request

curl "https://rest.tsheets.com/api/v1/locations" \
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/locations");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/locations")
Dim request = New RestRequest(Method.[GET])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/locations")
  .get()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/locations",
  "method": "GET",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'GET',
  url: 'https://rest.tsheets.com/api/v1/locations',
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/locations');
$request->setMethod(HTTP_METH_GET);

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/locations")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/locations"

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/locations"

  req, _ := http.NewRequest("GET", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/locations")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest, completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/locations"; 

$client->GET($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Example: Retrieve a list of all locations (active or deleted) with geocoding_status of 'complete'. Set pagination to 10 results/page.

Request

curl "https://rest.tsheets.com/api/v1/locations?geocoding_status=complete&limit=10&active=both" \
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/locations?geocoding_status=complete&limit=10&active=both");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/locations?geocoding_status=complete&limit=10&active=both")
Dim request = New RestRequest(Method.[GET])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/locations?geocoding_status=complete&limit=10&active=both")
  .get()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/locations?geocoding_status=complete&limit=10&active=both",
  "method": "GET",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'GET',
  url: 'https://rest.tsheets.com/api/v1/locations',
  qs: {
    geocoding_status: 'complete',
    limit: '10',
    active: 'both',
  },
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/locations');
$request->setMethod(HTTP_METH_GET);

$request->setQueryData(array(
  'geocoding_status' => 'complete',
  'limit' => '10',
  'active' => 'both',
));

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/locations?geocoding_status=complete&limit=10&active=both")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/locations"

querystring = {
  "geocoding_status":"complete",
  "limit":"10",
  "active":"both",
}

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/locations?geocoding_status=complete&limit=10&active=both"

  req, _ := http.NewRequest("GET", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/locations?geocoding_status=complete&limit=10&active=both")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest, completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/locations?geocoding_status=complete&limit=10&active=both"; 

$client->GET($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Example: Retrieve a list of customfielditems belonging to the given customfield and having given ids.

Request

curl "https://rest.tsheets.com/api/v1/locations?ids=12,367,3489" \
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/locations?ids=12,367,3489");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/locations?ids=12,367,3489")
Dim request = New RestRequest(Method.[GET])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/locations?ids=12,367,3489")
  .get()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/locations?ids=12,367,3489",
  "method": "GET",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'GET',
  url: 'https://rest.tsheets.com/api/v1/locations',
  qs: {
    ids: '12,367,3489',
  },
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/locations');
$request->setMethod(HTTP_METH_GET);

$request->setQueryData(array(
  'ids' => '12,367,3489',
));

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/locations?ids=12,367,3489")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/locations"

querystring = {
  "ids":"12,367,3489",
}

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/locations?ids=12,367,3489"

  req, _ := http.NewRequest("GET", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/locations?ids=12,367,3489")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest, completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/locations?ids=12,367,3489"; 

$client->GET($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Example: Retrieve a list of locations that have been modified since a given date.

Request

curl "https://rest.tsheets.com/api/v1/locations?modified_since=2018-01-01T00:00:00-06:00" \
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/locations?modified_since=2018-01-01T00:00:00-06:00");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/locations?modified_since=2018-01-01T00:00:00-06:00")
Dim request = New RestRequest(Method.[GET])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/locations?modified_since=2018-01-01T00:00:00-06:00")
  .get()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/locations?modified_since=2018-01-01T00:00:00-06:00",
  "method": "GET",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'GET',
  url: 'https://rest.tsheets.com/api/v1/locations',
  qs: {
    modified_since: '2018-01-01T00:00:00-06:00',
  },
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/locations');
$request->setMethod(HTTP_METH_GET);

$request->setQueryData(array(
  'modified_since' => '2018-01-01T00:00:00-06:00',
));

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/locations?modified_since=2018-01-01T00:00:00-06:00")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/locations"

querystring = {
  "modified_since":"2018-01-01T00:00:00-06:00",
}

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/locations?modified_since=2018-01-01T00:00:00-06:00"

  req, _ := http.NewRequest("GET", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/locations?modified_since=2018-01-01T00:00:00-06:00")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest, completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/locations?modified_since=2018-01-01T00:00:00-06:00"; 

$client->GET($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "locations": {
      "65305": {
        "id": 65305,
        "addr1": "235 E Colchester Dr",
        "addr2": "101",
        "city": "Eagle",
        "state": "ID",
        "zip": "83616",
        "country": "US",
        "formatted_address": "235 E Colchester Dr 101, Eagle, ID 83616",
        "active": true,
        "latitude": 43.6700273,
        "longitude": -116.3520972,
        "place_id": "",
        "place_id_hash": "0ba5eaf96c5f63c3b76d5084c365b6e4",
        "label": "TSheets, East Colchester Drive, Eagle, ID, USA",
        "notes": "",
        "geocoding_status": "complete",
        "created": "2018-03-09T18:26:57+00:00",
        "last_modified": "2018-03-15T16:51:14+00:00",
        "linked_objects": {
          "jobcodes": [
            2589531
          ]
        },
        "geofence_config_id": null
      },
      "78135": {
        "id": 78135,
        "addr1": "Hollywood Blvd",
        "addr2": "",
        "city": "Los Angeles",
        "state": "CA",
        "zip": "",
        "country": "US",
        "formatted_address": "Hollywood Blvd, Los Angeles, CA",
        "active": true,
        "latitude": 34.1015885,
        "longitude": -118.3336436,
        "place_id": "",
        "place_id_hash": "8c43103323bb0b1ce7c4094029029914",
        "label": "Hollywood Boulevard, Los Angeles, CA, USA",
        "notes": "",
        "geocoding_status": "complete",
        "created": "2018-03-19T22:52:04+00:00",
        "last_modified": "2018-04-19T16:29:14+00:00",
        "linked_objects": {},
        "geofence_config_id": 1393
      }
    }
  },
  "more": false,
  "supplemental_data": {
    "jobcodes": {
      "2589531": {
        "id": 2589531,
        "active": true,
        "parent_id": 0,
        "assigned_to_all": false,
        "type": "regular",
        "billable": false,
        "billable_rate": 5,
        "short_code": "",
        "name": "Technology",
        "created": "2018-03-15T15:50:50+0000",
        "last_modified": "2018-03-15T23:09:27+0000",
        "has_children": false,
        "required_customfields": [],
        "filtered_customfielditems": "",
        "locations": [
          65305
        ]
      }
    },
    "geofence_configs": {
      "1393": {
        "id": 1393,
        "active": true,
        "type": "locations",
        "type_id": 78135,
        "enabled": true,
        "radius": 125,
        "created": "2018-05-20T12:34:56+00:00",
        "last_modified": "2018-05-20T12:34:56+00:00"
      }
    }
  }
}

Retrieves a list of all locations associated with your company, with optional filters to narrow down the results.

HTTP Request

gethttps://rest.tsheets.com/api/v1/locations

Filter Parameters

ids
optional
Int Comma separated list of one or more location ids you'd like to filter on. Only locations with an id set to one of these values will be returned. If omitted, all locations matching other specified filters are returned.
active
optional
String 'yes', 'no', or 'both'. Default is 'yes'. If a location is active, it is available for selection during time entry.
geocoding_status
optional
String Comma separated list of one or more of the following values: 'none', 'in_progress', 'retry', 'error', or 'complete'. If omitted, all locations matching other specified filters are returned.
modified_before
optional
String Only locations modified before this date/time will be returned, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm)
modified_since
optional
String Only locations modified since this date/time will be returned, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm)
supplemental_data
optional
String 'yes' or 'no'. Default is 'yes'. Indicates whether supplemental data should be returned.
per_page
optional
Int Deprecated. Use limit for new code.
Represents how many results you'd like to retrieve per request. Default is 50. Max is 50.
If a value over 50 is provided, it is ignored, and the max is used.
limit
optional
Int Represents how many results you'd like to retrieve per request. Default is 200. Max is 200.
If present, this value must be: an integer, greater than zero, and not greater than 200.
Setting limit less than 1 or greater than 200 will result in an error.
page
optional
Int Represents the page of results you'd like to retrieve. Default is 1.
by_jobcode_assignment
optional
Boolean true or false. If specified, only locations mapped to a jobcode the user is assigned to will be returned.

Create Locations

Example: Create two new locations. One of them linked to an existing jobcode.

Request Body

{
  "data": [{
    "addr1": "235 E Colchester Dr",
    "addr2": "101",
    "city": "Eagle",
    "state": "ID",
    "zip": "83616",
    "country": "US",
    "formatted_address": "235 E Colchester Dr, Meridian, ID 83646",
    "active": true,
    "label": "TSheets HQ",
    "notes": "Please use front door",
    "linked_objects": {
      "jobcodes": [
        3656485
      ]
    }
  }, {
    "addr1": "7 Any Street",
    "addr2": "",
    "city": "Meridian",
    "state": "ID",
    "zip": "83646",
    "country": "US",
    "formatted_address": "7 Any Street, Meridian, ID 83646",
    "active": true,
    "label": "Any House on Any Street",
    "notes": "Beware the dog!"
  }]
}

Request

curl -X POST \
  https://rest.tsheets.com/api/v1/locations \
  -H 'Authorization: Bearer <TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '<REQUEST BODY>'
var client = new RestClient("https://rest.tsheets.com/api/v1/locations");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <TOKEN>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "<REQUEST BODY>", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/locations")
Dim request = New RestRequest(Method.POST)
request.AddHeader("Authorization", "Bearer <TOKEN>")
request.AddHeader("Content-Type", "application/json")
request.AddParameter("application/json", "<REQUEST BODY>", ParameterType.RequestBody);
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<REQUEST BODY>");
Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/locations")
  .post(body)
  .addHeader("Authorization", "Bearer <TOKEN>")
  .addHeader("Content-Type", "application/json")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/locations?modified_since=2018-01-01T00:00:00-06:00",
  "method": "POST",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
    "Content-Type", "application/json",
  },
  "processData": false,
  "data": "<REQUEST BODY>"
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'POST',
  url: 'https://rest.tsheets.com/api/v1/locations',
  headers: 
  { 
     'Authorization': 'Bearer <TOKEN>',
     'Content-Type': 'application/json',
  },
  body: '<REQUEST BODY>',
  json: true };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/locations');
$request->setMethod(HTTP_METH_POST);

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
  'Content-Type' => 'application/json',
));

$request->setBody('<REQUEST BODY>');

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/locations")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <TOKEN>',
request["Content-Type"] = 'application/json',
request.body = "<REQUEST BODY>"

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/locations"

payload = "<REQUEST BODY>"
headers = {
    'Authorization': 'Bearer <TOKEN>',
    'Content-Type': 'application/json',
    }

response = requests.request("POST", url, data=payload, headers=headers)

print(response.text)
package main

import (
  "fmt"
  "strings"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/locations"

  payload := strings.NewReader("<REQUEST BODY>")

  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, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))

}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
   "Content-Type": "application/json",
]
let parameters = <REQUEST BODY> as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/locations")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest,
  completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');
$client->addHeader('Content-Type', 'application/json');

$req = '<REQUEST BODY>';

$url="https://rest.tsheets.com/api/v1/locations"; 

$client->POST($url, $req);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "locations": {
      "1": {
        "_status_code": 200,
        "_status_message": "Created",
        "id": 742413,
        "addr1": "235 E Colchester Dr",
        "addr2": "101",
        "city": "Eagle",
        "state": "ID",
        "zip": "83616",
        "formatted_address": "235 E Colchester Dr 101, Eagle, ID 83616",
        "country": "US",
        "active": true,
        "latitude": 0,
        "longitude": 0,
        "place_id": "",
        "place_id_hash": "",
        "label": "TSheets HQ",
        "notes": "Please use the front door",
        "geocoding_status": "none",
        "created": "2018-12-18T18:01:01+00:00",
        "last_modified": "2018-12-18T18:01:01+00:00",
        "linked_objects": {
          "jobcodes": [
            3656485
          ]
        },
        "geofence_config_id": null
      },
      "2": {
        "_status_code": 200,
        "_status_message": "Created",
        "id": 742415,
        "addr1": "7 Any Street",
        "addr2": "",
        "city": "Meridian",
        "state": "ID",
        "zip": "83646",
        "formatted_address": "7 Any Street, Meridian, ID 83646",
        "country": "US",
        "active": true,
        "latitude": 0,
        "longitude": 0,
        "place_id": "",
        "place_id_hash": "",
        "label": "Any House on Any Street",
        "notes": "Beware the dog!",
        "geocoding_status": "none",
        "created": "2018-12-18T18:01:01+00:00",
        "last_modified": "2018-12-18T18:01:01+00:00",
        "linked_objects": {},
        "geofence_config_id": null
      }
    }
  },
  "supplemental_data": {
    "jobcodes": {
      "3656485": {
        "id": 3656485,
        "active": true,
        "parent_id": 0,
        "assigned_to_all": true,
        "type": "regular",
        "billable": true,
        "billable_rate": 0,
        "short_code": "",
        "name": "Gutter Cleaning",
        "created": "2018-10-31T15:15:25+0000",
        "last_modified": "2018-12-13T15:11:57+0000",
        "has_children": false,
        "required_customfields": [
          326759
        ],
        "filtered_customfielditems": {
          "326759": [
            2207167
          ]
        },
        "locations": [
          742413
        ]
      }
    }
  }
}

Add one or more locations to your company.

HTTP Request

posthttps://rest.tsheets.com/api/v1/locations

Properties

Pass an array of location objects as the value to a 'data' property (see example).

One or more of the following properties are required to create a location:

addr1 String The first line of the street for the address.
addr2 String The second line of the street for the address.
city String The city of the address.
state String The state of the address.
zip String The postal code for the address.
country String The country of the address.

For a full list of properties that may be set on a location, see the Location object.

Status Codes

Each location that is created will come back with a _status_code and _status_message that will indicate whether the location was created successfully. If there was a problem creating a location, there may also be an additional field, _status_extra, which will contain more details about the failure.

200 OK. Location was created successfully.
417 Expectation Failed. Something was wrong or missing with the properties supplied for this location. See the _status_extra value for more detail.

Update Locations

Example: Change some information for each of these locations as well as unlink one of the location from a jobcode.

Request Body

{
  "data": [{
    "id": 742413,
    "addr1": "235 E Colchester Dr",
    "addr2": "101",
    "city": "Eagle",
    "state": "ID",
    "zip": "83616",
    "country": "US",
    "formatted_address": "235 E Colchester Dr, Meridian, ID 83646",
    "active": true,
    "label": "TSheets HQ",
    "notes": "Please use the front door",
    "linked_objects": {
      "jobcodes": [

      ]
    }
  }, {
    "id": 742415,
    "addr1": "8 Any Street",
    "addr2": "",
    "city": "Meridian",
    "state": "ID",
    "zip": "83646",
    "country": "US",
    "formatted_address": "7 Any Street, Meridian, ID 83646",
    "active": true,
    "label": "Any House on Any Street",
    "notes": "Beware the dog!"
  }]
}

Request

curl -X PUT \
  https://rest.tsheets.com/api/v1/locations \
  -H 'Authorization: Bearer <TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '<REQUEST BODY>'
var client = new RestClient("https://rest.tsheets.com/api/v1/locations");
var request = new RestRequest(Method.PUT);
request.AddHeader("Authorization", "Bearer <TOKEN>");
request.AddHeader("Content-Type", "application/json");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/locations")
Dim request = New RestRequest(Method.PUT)
request.AddHeader("Authorization", "Bearer <TOKEN>")
request.AddHeader("Content-Type", "application/json")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<REQUEST BODY>");
Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/locations")
  .put(body)
  .addHeader("Authorization", "Bearer <TOKEN>")
  .addHeader("Content-Type", "application/json")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/locations?modified_since=2018-01-01T00:00:00-06:00",
  "method": "PUT",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
    "Content-Type", "application/json",
  },
  "processData": false,
  "data": "<REQUEST BODY>"
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'PUT',
  url: 'https://rest.tsheets.com/api/v1/locations',
  headers: 
  { 
     'Authorization': 'Bearer <TOKEN>',
     'Content-Type': 'application/json',
  },
  body: '<REQUEST BODY>',
  json: true };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/locations');
$request->setMethod(HTTP_METH_PUT);

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
  'Content-Type' => 'application/json',
));

$request->setBody('<REQUEST BODY>');

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/locations")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <TOKEN>',
request["Content-Type"] = 'application/json',
request.body = "<REQUEST BODY>"

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/locations"

payload = "<REQUEST BODY>"
headers = {
    'Authorization': 'Bearer <TOKEN>',
    'Content-Type': 'application/json',
    }

response = requests.request("PUT", url, data=payload, headers=headers)

print(response.text)
package main

import (
  "fmt"
  "strings"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/locations"

  payload := strings.NewReader("<REQUEST BODY>")

  req, _ := http.NewRequest("PUT", 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, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))

}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
   "Content-Type": "application/json",
]
let parameters = <REQUEST BODY> as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(
  url: NSURL(string: "http://rest.tsheets.com/api/v1/locations")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "PUT"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest,
  completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');
$client->addHeader('Content-Type', 'application/json');

$req = '<REQUEST BODY>';

$url="http://rest.tsheets.com/api/v1/locations"; 

$client->PUT($url, $req);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "locations": {
      "1": {
        "_status_code": 200,
        "_status_message": "Updated",
        "id": 742413,
        "addr1": "235 E Colchester Dr",
        "addr2": "101",
        "city": "Eagle",
        "state": "ID",
        "zip": "83616",
        "formatted_address": "235 E Colchester Dr 101, Eagle, ID 83616",
        "country": "US",
        "active": true,
        "latitude": 43.6698951,
        "longitude": -116.3522866,
        "place_id": "",
        "place_id_hash": "c2ed7ff7a2abadf503d2ffd4f1736ca4",
        "label": "TSheets HQ",
        "notes": "Please use the front door",
        "geocoding_status": "complete",
        "created": "2018-12-18T18:01:01+00:00",
        "last_modified": "2018-12-18T18:24:56+00:00",
        "linked_objects": {},
        "geofence_config_id": null
      },
      "2": {
        "_status_code": 200,
        "_status_message": "Updated",
        "id": 742415,
        "addr1": "8 Any Street",
        "addr2": "",
        "city": "Meridian",
        "state": "ID",
        "zip": "83646",
        "formatted_address": "8 Any Street, Meridian, ID 83646",
        "country": "US",
        "active": true,
        "latitude": 43.6141813,
        "longitude": -116.4029894,
        "place_id": "",
        "place_id_hash": "c261737fbcc29174cdbc8fa2f62da13d",
        "label": "Any House on Any Street",
        "notes": "Beware the dog!",
        "geocoding_status": "complete",
        "created": "2018-12-18T18:01:01+00:00",
        "last_modified": "2018-12-18T18:25:51+00:00",
        "linked_objects": {},
        "geofence_config_id": null
      }
    }
  },
  "supplemental_data": {
    "jobcodes": {
      "3656485": {
        "id": 3656485,
        "active": true,
        "parent_id": 0,
        "assigned_to_all": true,
        "type": "regular",
        "billable": true,
        "billable_rate": 0,
        "short_code": "",
        "name": "A_Test_Of_Add_0",
        "created": "2018-10-31T15:15:25+0000",
        "last_modified": "2018-12-13T15:11:57+0000",
        "has_children": false,
        "required_customfields": [
          326759
        ],
        "filtered_customfielditems": {
          "326759": [
            2207167
          ]
        },
        "locations": []
      }
    }
  }
}

Edit one or more locations in your company.

HTTP Request

puthttps://rest.tsheets.com/api/v1/locations

Properties

Pass an array of location objects as the value to a 'data' property (see example).

id
required
Int Id of the location.

Other properties defined on a location object may be passed in to the request with a new value in order to change it. If the value passed in is the same as it was previously, or if a particular property is not passed in at all, it will be ignored.

Status Codes

Each location that is edited will come back with a _status_code and _status_message that will indicate whether the location was edited successfully. If there was a problem editing a location, there may also be an additional field, _status_extra, which will contain more details about the failure.

200 OK. Location was edited successfully.
417 Expectation Failed. Something was wrong or missing with the properties supplied for this location. See the _status_extra value for more detail.

Locations Maps

The Locations Map Object

Example

{
  "id": 102839,
  "x_table": "job_codes",
  "x_id": 2597003,
  "location_id": 237053,
  "created": "2018-06-20T14:14:26+00:00",
  "last_modified": "2018-08-01T10:31:16+00:00"
}

Following is a list of the properties that belong to a locations map object, and a description of each.

id
read-only
Int Id of locations map.
x_table
read-write
String The name of the entity the location is mapped to.
x_id
read-write
Int The id of the entity the location is mapped to.
location_id
read-write
Int The id of the location that is mapped to the entity.
last_modified
read-only
String Date/time when this locations map was last modified, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm)
created
read-only
String Date/time when this locations map was created, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm)

Retrieve Locations Maps

Example: Retrieve a list of all active locations maps.

Request

curl "https://rest.tsheets.com/api/v1/locations_map" \
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/locations_map");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/locations_map")
Dim request = New RestRequest(Method.[GET])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/locations_map")
  .get()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/locations_map",
  "method": "GET",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'GET',
  url: 'https://rest.tsheets.com/api/v1/locations_map',
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/locations_map');
$request->setMethod(HTTP_METH_GET);

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/locations_map")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/locations_map"

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/locations_map"

  req, _ := http.NewRequest("GET", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/locations_map")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest, completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/locations_map"; 

$client->GET($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Example: Retrieve a list of locations maps with given ids.

Request

curl "https://rest.tsheets.com/api/v1/locations_map?ids=12,367,3489" \
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/locations_map?ids=12,367,3489");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/locations_map?ids=12,367,3489")
Dim request = New RestRequest(Method.[GET])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/locations_map?ids=12,367,3489")
  .get()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/locations_map?ids=12,367,3489",
  "method": "GET",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'GET',
  url: 'https://rest.tsheets.com/api/v1/locations_map',
  qs: {
    ids: '12,367,3489',
  },
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/locations_map');
$request->setMethod(HTTP_METH_GET);

$request->setQueryData(array(
  'ids' => '12,367,3489',
));

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/locations_map?ids=12,367,3489")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/locations_map"

querystring = {
  "ids":"12,367,3489",
}

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/locations_map?ids=12,367,3489"

  req, _ := http.NewRequest("GET", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/locations_map?ids=12,367,3489")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest, completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/locations_map?ids=12,367,3489"; 

$client->GET($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Example: Retrieve a list of locations maps that have been modified since a given date.

Request

curl "https://rest.tsheets.com/api/v1/locations_map?modified_since=2018-01-01T00:00:00-06:00" \
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/locations_map?modified_since=2018-01-01T00:00:00-06:00");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/locations_map?modified_since=2018-01-01T00:00:00-06:00")
Dim request = New RestRequest(Method.[GET])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/locations_map?modified_since=2018-01-01T00:00:00-06:00")
  .get()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/locations_map?modified_since=2018-01-01T00:00:00-06:00",
  "method": "GET",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'GET',
  url: 'https://rest.tsheets.com/api/v1/locations_map',
  qs: {
    modified_since: '2018-01-01T00:00:00-06:00',
  },
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/locations_map');
$request->setMethod(HTTP_METH_GET);

$request->setQueryData(array(
  'modified_since' => '2018-01-01T00:00:00-06:00',
));

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/locations_map?modified_since=2018-01-01T00:00:00-06:00")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/locations_map"

querystring = {
  "modified_since":"2018-01-01T00:00:00-06:00",
}

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/locations_map?modified_since=2018-01-01T00:00:00-06:00"

  req, _ := http.NewRequest("GET", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/locations_map?modified_since=2018-01-01T00:00:00-06:00")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest, completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/locations_map?modified_since=2018-01-01T00:00:00-06:00"; 

$client->GET($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "locations_map": {
      "102839": {
        "id": 102839,
        "x_table": "job_codes",
        "x_id": 2597003,
        "location_id": 237053,
        "created": "2018-06-20T14:14:26+00:00",
        "last_modified": "2018-08-01T10:31:16+00:00"
      },
      "110761": {
        "id": 110761,
        "x_table": "job_codes",
        "x_id": 3003037,
        "location_id": 268919,
        "created": "2018-07-10T14:33:14+00:00",
        "last_modified": "2018-08-01T10:31:16+00:00"
      }
    }
  },
  "supplemental_data": {
    "locations": {
      "237053": {
        "id": 237053,
        "addr1": "1234 N Back Rd",
        "addr2": "",
        "city": "Eagle",
        "state": "ID",
        "zip": "83616",
        "formatted_address": "1234 N Back Rd, Eagle, ID 83616",
        "country": "US",
        "active": true,
        "latitude": 43.648051,
        "longitude": -116.353473,
        "place_id": "",
        "place_id_hash": "a08b7c81255ef0d67f5c2a0e55858c1b",
        "label": "1234 North Back Road, Eagle, ID, USA",
        "notes": "",
        "geocoding_status": "complete",
        "created": "2018-06-26T19:49:55+00:00",
        "last_modified": "2018-06-26T19:49:55+00:00",
        "linked_objects": {
          "jobcodes": [
            2597003
          ]
        },
        "geofence_config_id": 116905
      },
      "268919": {
        "id": 268919,
        "addr1": "5678 E Cole Dr",
        "addr2": "",
        "city": "Eagle",
        "state": "ID",
        "zip": "83616",
        "formatted_address": "5678 E Cole Dr, Eagle, ID 83616",
        "country": "US",
        "active": true,
        "latitude": 43.670013,
        "longitude": -116.3521704,
        "place_id": "",
        "place_id_hash": "d6c4ea86ec37bf0fa5e01194d19adf29",
        "label": "5678 East Cole Drive, Eagle, ID, USA",
        "notes": "",
        "geocoding_status": "complete",
        "created": "2018-07-10T14:33:14+00:00",
        "last_modified": "2018-07-10T14:33:14+00:00",
        "linked_objects": {
          "jobcodes": [
            3003037
          ]
        },
        "geofence_config_id": null
      }
    }
  }
}

Retrieves a list of all locations maps associated with your company, with optional filters to narrow down the results.

HTTP Request

gethttps://rest.tsheets.com/api/v1/locations_map

Filter Parameters

ids
optional
Int Comma separated list of one or more locations map ids you'd like to filter on. Only locations maps with an id set to one of these values will be returned. If omitted, all locations maps matching other specified filters are returned.
active
optional
String 'yes', 'no', or 'both'. Default is 'yes'.
modified_before
optional
String Only locations maps modified before this date/time will be returned, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm)
modified_since
optional
String Only locations maps modified since this date/time will be returned, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm)
per_page
optional
Int Deprecated. Use limit for new code.
Represents how many results you'd like to retrieve per request. Default is 50. Max is 50.
If a value over 50 is provided, it is ignored, and the max is used.
limit
optional
Int Represents how many results you'd like to retrieve per request. Default is 200. Max is 200.
If present, this value must be: an integer, greater than zero, and not greater than 200.
Setting limit less than 1 or greater than 200 will result in an error.
page
optional
Int Represents the page of results you'd like to retrieve.
by_jobcode_assignment
optional
Boolean true or false. If specified only locations maps mapped to a jobcode the user is assigned to will be returned.

Managed Clients

The Managed Client Object

Example

{ 
  "id":"1146",
  "company_url":"acmedev",
  "company_name":"Acme Dev",
  "active":true,
  "created":"2018-05-31T16:52:50+00:00",
  "last_modified":"2018-08-08T22:23:34+00:00"
}

Following is a list of the properties that belong to a managed client object, and a description of each

id
read-only
Int Id of the managed client.
company_url
read-only
String URL used by the managed client to sign in to TSheets.
company_name
read-only
String Name of the managed client's company.
active
read-write
Boolean If false, this client is considered archived.
created
read-only
String Date/time when this managed client record was created, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm)
last_modified
read-only
String Date/time when this managed client record was last modified, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm)

Retrieve Managed Clients

Example: Retrieve a list of all managed clients under your account.

Request

curl "https://rest.tsheets.com/api/v1/managed_clients" \
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/managed_clients");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/managed_clients")
Dim request = New RestRequest(Method.[GET])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/managed_clients")
  .get()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/managed_clients",
  "method": "GET",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'GET',
  url: 'https://rest.tsheets.com/api/v1/managed_clients',
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/managed_clients');
$request->setMethod(HTTP_METH_GET);

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/managed_clients")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/managed_clients"

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/managed_clients"

  req, _ := http.NewRequest("GET", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/managed_clients")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest, completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/managed_clients"; 

$client->GET($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{ 
  "results":{ 
   "managed_clients":{ 
     "1146":{ 
      "id":"1146",
      "company_url":"acmedev",
      "company_name":"Acme Dev",
      "active":true,
      "created":"2018-05-31T16:52:50+00:00",
      "last_modified":"2018-08-08T22:23:34+00:00"
     },
     "1232":{ 
      "id":"1232",
      "company_url":"acmetrucking",
      "company_name":"Acme Trucking",
      "active":true,
      "created":"2018-07-13T20:14:52+00:00",
      "last_modified":"2018-07-13T20:19:12+00:00"
     },
     "1274":{ 
      "id":"1274",
      "company_url":"bodacious",
      "company_name":"Bodacious Swine",
      "active":false,
      "created":"2018-08-09T17:21:28+00:00",
      "last_modified":"2018-08-09T17:22:44+00:00"
     },
     "1233":{ 
      "id":"1233",
      "company_url":"acmeclean",
      "company_name":"Acme Cleaning",
      "active":false,
      "created":"2018-07-13T20:32:46+00:00",
      "last_modified":"2018-07-13T20:35:06+00:00"
     }
   },
   "more":false
  }
}

Retrieves a list of managed clients available from your account.

HTTP Request

gethttps://rest.tsheets.com/api/v1/managed_clients

Filter Parameters

active
optional
String 'yes', 'no', or 'both'. Default is 'yes'.
per_page
optional
Int Deprecated. Use limit for new code.
Represents how many results you'd like to retrieve per request. Default is 50. Max is 50.
If a value over 50 is provided, it is ignored, and the max is used.
limit
optional
Int Represents how many results you'd like to retrieve per request. Default is 200. Max is 200.
If present, this value must be: an integer, greater than zero, and not greater than 200.
Setting limit less than 1 or greater than 200 will result in an error.
page
optional
Int Represents the page of results you'd like to retrieve. Default is 1.

Managing Clients

Example: Retrieve the users on a managed client's account.

Request

curl "https://rest.tsheets.com/api/v1/managed_clients" \
  -H "Authorization: Bearer <TOKEN>" \
  -H "vnd.tsheets.ManagedClientId: <Managed-Client-Id>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/managed_clients");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <TOKEN>");
request.AddHeader("vnd.tsheets.ManagedClientId", "<Managed-Client-Id>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/managed_clients")
Dim request = New RestRequest(Method.[GET])
request.AddHeader("Authorization", "Bearer <TOKEN>")
request.AddHeader("vnd.tsheets.ManagedClientId", "<Managed-Client-Id>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/managed_clients")
  .get()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .addHeader("vnd.tsheets.ManagedClientId", "<Managed-Client-Id>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/managed_clients",
  "method": "GET",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
    "vnd.tsheets.ManagedClientId", "<Managed-Client-Id>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'GET',
  url: 'https://rest.tsheets.com/api/v1/managed_clients',
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
     'vnd.tsheets.ManagedClientId': '<Managed-Client-Id>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/managed_clients');
$request->setMethod(HTTP_METH_GET);

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
  'vnd.tsheets.ManagedClientId' => '<Managed-Client-Id>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/managed_clients")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <TOKEN>',
request["vnd.tsheets.ManagedClientId"] = '<Managed-Client-Id>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/managed_clients"

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
   'vnd.tsheets.ManagedClientId': "<Managed-Client-Id>",
  }

response = requests.request("GET", url, data=payload, headers=headers)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/managed_clients"

  req, _ := http.NewRequest("GET", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")
  req.Header.Add("vnd.tsheets.ManagedClientId", "<Managed-Client-Id>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
   "vnd.tsheets.ManagedClientId": "<Managed-Client-Id>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/managed_clients")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest, completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');
$client->addHeader('vnd.tsheets.ManagedClientId', '<Managed-Client-Id>');

$url="https://rest.tsheets.com/api/v1/managed_clients"; 

$client->GET($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
    "results": {
      "managed_clients": {
        "1146": { 
          "id":"1146",
          "company_url":"acmedev",
          "company_name":"Acme Dev",
          "active":true,
          "created":"2018-05-31T16:52:50+00:00",
          "last_modified":"2018-08-08T22:23:34+00:00"
        }
      }
    },
    "more": false
}

If you have the External Access add-on installed, you can make API requests using your auth token against clients that you manage. When you want to make an API request against one of the clients that you manage, you must include an additional header in each request, vnd.tsheets.ManagedClientId.

The value of the header is the client ID of the account you are managing. You can obtain the client IDs of the clients you manage by issuing a GET on the /managed_clients endpoint.

Notifications

The Notification Object

Example

{
  "id": 94140223,
  "msg_tracking_id": "baabeb0ab03d62ce",
  "user_id": 1242515,
  "message": "Please clock in!",
  "method": "push",
  "delivery_time": "2018-06-24T15:00:00+00:00",
  "created": "2018-06-23T14:17:57+00:00",
  "precheck": "off_the_clock"
}

Following is a list of the properties that belong to a notification, and a description of each.

id
read-only
Int Id of notification.
user_id
read-write
Int User id for the user that this notification will be sent to.
msg_tracking_id
read-only
String A GUID string used for additional tracking.
message
read-write
String The message text of the notification. The maximum message length is 2000 characters.
method
read-write
String The transport method of the notification. We support 'push', 'email', and 'dashboard'. The 'push' method utilizes the TSheets mobile app to deliver the notification to a mobile device. The 'email' method sends an Email to the user (if they have an Email address). The 'dashboard' method utilizes the TSheets web dashboard notification queue to deliver a notification to the user. They will only see this when they're logged in to the TSheets web app.
precheck
read-write
String The precheck macro name. Supported macros are 'on_the_clock', 'off_the_clock', and 'none'. The 'on_the_clock' macro will first check if the recipient is on the clock before sending and if not, will discard the notification. The 'off_the_clock' macro will first check if the recipient is off the clock (and not on PTO) before sending and if not, will discard the notification. The 'none' macro (the default) will not perform any checks before sending.
delivery_time
read-write
String Date/time when this notification will be delivered, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm). Defaults to the current time.
created
read-only
String Date/time when this notification was created, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm)

Retrieve Notifications

Example: Retrieve a list of all notifications scheduled for a specific user.

Request

curl "https://rest.tsheets.com/api/v1/notifications?user_id=1242515" \
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/notifications?user_id=1242515");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/notifications?user_id=1242515")
Dim request = New RestRequest(Method.[GET])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/notifications?user_id=1242515")
  .get()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/notifications?user_id=1242515",
  "method": "GET",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'GET',
  url: 'https://rest.tsheets.com/api/v1/notifications',
  qs: {
    user_id: '1242515',
  },
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/notifications');
$request->setMethod(HTTP_METH_GET);

$request->setQueryData(array(
  'user_id' => '1242515',
));

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/notifications?user_id=1242515")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/notifications"

querystring = {
  "user_id":"1242515",
}

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/notifications?user_id=1242515"

  req, _ := http.NewRequest("GET", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/notifications?user_id=1242515")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest, completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/notifications?user_id=1242515"; 

$client->GET($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "notifications": {
      "94140225": {
        "id": 94140223,
        "msg_tracking_id": "baabeb0ab03d62ce",
        "user_id": 1242515,
        "message": "Please clock in!",
        "method": "push",
        "delivery_time": "2018-06-24T15:00:00+00:00",
        "created": "2018-06-23T14:17:57+00:00",
        "precheck": "off_the_clock"
      },
      "94140225": {
        "id": 94140225,
        "msg_tracking_id": "3ce75c1b7de6598a",
        "user_id": 1242515,
        "message": "Please clock out!",
        "method": "push",
        "delivery_time": "2018-06-24T23:00:00+00:00",
        "created": "2018-06-23T14:17:57+00:00",
        "precheck": "on_the_clock"
      }
    },
    "more": false
  }
}

Retrieves a list of notifications associated with your company, with filters to narrow down the results.

HTTP Request

gethttps://rest.tsheets.com/api/v1/notifications

Filter Parameters

If no filters are set, all notifications for the requesting user (based on the Access-Token) will be returned.

ids
optional
Int Comma separated list of one or more notification ids you'd like to filter on. Only notifications with an id set to one of these values will be returned.
delivery_before
optional
String Only notifications with a delivery date/time before this date/time will be returned, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm).
delivery_after
optional
String Only notifications with a delivery date/time after this date/time will be returned, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm).
user_id
optional
Int Only notifications linked to this user ID will be returned.
msg_tracking_id
optional
String Tracking ID string of a notification. Only the notification with this msg_tracking_id will be returned.
per_page
optional
Int Deprecated. Use limit for new code.
Represents how many results you'd like to retrieve per request. Default is 50. Max is 50.
If a value over 50 is provided, it is ignored, and the max is used.
limit
optional
Int Represents how many results you'd like to retrieve per request. Default is 200. Max is 200.
If present, this value must be: an integer, greater than zero, and not greater than 200.
Setting limit less than 1 or greater than 200 will result in an error.
page
optional
Int Represents the page of results you'd like to retrieve. Default is 1.

Create Notifications

Example: Create two new notifications.

Request Body

{
  "data": [{
    "user_id": 1242515,
    "method": "push",
    "delivery_time": "2018-06-19T14:00:00+00:00",
    "precheck": "off_the_clock",
    "message": "Please clock in!"
  }, {
    "user_id": 1242515,
    "method": "push",
    "delivery_time": "2018-06-19T23:00:00+00:00",
    "precheck": "on_the_clock",
    "message": "Please clock out!"
  }]
}

Request

curl -X POST \
  https://rest.tsheets.com/api/v1/notifications \
  -H 'Authorization: Bearer <TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '<REQUEST BODY>'
var client = new RestClient("https://rest.tsheets.com/api/v1/notifications");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <TOKEN>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "<REQUEST BODY>", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/notifications")
Dim request = New RestRequest(Method.POST)
request.AddHeader("Authorization", "Bearer <TOKEN>")
request.AddHeader("Content-Type", "application/json")
request.AddParameter("application/json", "<REQUEST BODY>", ParameterType.RequestBody);
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<REQUEST BODY>");
Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/notifications")
  .post(body)
  .addHeader("Authorization", "Bearer <TOKEN>")
  .addHeader("Content-Type", "application/json")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/notifications?user_id=1242515",
  "method": "POST",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
    "Content-Type", "application/json",
  },
  "processData": false,
  "data": "<REQUEST BODY>"
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'POST',
  url: 'https://rest.tsheets.com/api/v1/notifications',
  headers: 
  { 
     'Authorization': 'Bearer <TOKEN>',
     'Content-Type': 'application/json',
  },
  body: '<REQUEST BODY>',
  json: true };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/notifications');
$request->setMethod(HTTP_METH_POST);

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
  'Content-Type' => 'application/json',
));

$request->setBody('<REQUEST BODY>');

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/notifications")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <TOKEN>',
request["Content-Type"] = 'application/json',
request.body = "<REQUEST BODY>"

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/notifications"

payload = "<REQUEST BODY>"
headers = {
    'Authorization': 'Bearer <TOKEN>',
    'Content-Type': 'application/json',
    }

response = requests.request("POST", url, data=payload, headers=headers)

print(response.text)
package main

import (
  "fmt"
  "strings"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/notifications"

  payload := strings.NewReader("<REQUEST BODY>")

  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, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))

}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
   "Content-Type": "application/json",
]
let parameters = <REQUEST BODY> as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/notifications")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest,
  completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');
$client->addHeader('Content-Type', 'application/json');

$req = '<REQUEST BODY>';

$url="https://rest.tsheets.com/api/v1/notifications"; 

$client->POST($url, $req);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "notifications": {
      "1": {
        "_status_code": 200,
        "_status_message": "Created",
        "id": 94140223,
        "msg_tracking_id": "baabeb0ab03d62ce",
        "user_id": 1242515,
        "message": "Please clock in!",
        "method": "push",
        "delivery_time": "2018-06-24T15:00:00+00:00",
        "created": "2018-06-23T14:17:57+00:00",
        "precheck": "off_the_clock"
      },
      "2": {
        "_status_code": 200,
        "_status_message": "Created",
        "id": 94140225,
        "msg_tracking_id": "3ce75c1b7de6598a",
        "user_id": 1242515,
        "message": "Please clock out!",
        "method": "push",
        "delivery_time": "2018-06-24T23:00:00+00:00",
        "created": "2018-06-23T14:17:57+00:00",
        "precheck": "on_the_clock"
      }
    }
  }
}s

Add one or more notifications.

HTTP Request

posthttps://rest.tsheets.com/api/v1/notifications

Properties

Pass an array of notification objects as the value to a 'data' property (see example).

message
required
String The message text of the notification. The maximum message length is 2000 characters.
user_id
optional
Int Defaults to the requesting user (based on the Access Token).

For a full list of the properties that may be set on a notification, see the Notification object.

Status Codes

Each notification that is created will come back with a _status_code and_status_message that will indicate whether the notification was created successfully. If there was a problem creating a notification, there may also be an additional field, _status_extra, which will contain more details about the failure.

200 OK. Notification was created successfully.
417 Expectation Failed. Something was wrong or missing with the properties supplied for this notification. See the _status_extra value for more detail.

General Notes

Delete Notifications

Example: Delete two notifications

Request

curl -X DELETE "https://rest.tsheets.com/api/v1/notifications?ids=135694294,135694494"
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/notifications?ids=135694294,135694494");
var request = new RestRequest(Method.DELETE);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/notifications?ids=135694294,135694494")
Dim request = New RestRequest(Method.[DELETE])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/notifications?ids=135694294,135694494")
  .delete()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/notifications?ids=135694294,135694494",
  "method": "DELETE",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'DELETE',
  url: 'https://rest.tsheets.com/api/v1/notifications',
  qs: {
    ids: '135694294,135694494',
  },
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/notifications');
$request->setMethod(HTTP_METH_DELETE);

$request->setQueryData(array(
  'ids' => '135694294,135694494',
));

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/notifications?ids=135694294,135694494")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Delete.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/notifications"

querystring = {
  "ids":"135694294,135694494",
}

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/notifications?ids=135694294,135694494"

  req, _ := http.NewRequest("DELETE", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/notifications?ids=135694294,135694494")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "DELETE"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/notifications?ids=135694294,135694494"; 

$client->DELETE($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "notifications": {
      "135694294": {
        "_status_code": 200,
        "_status_message": "OK, deleted",
        "id": "135694294"
      },
      "135694494": {
        "_status_code": 200,
        "_status_message": "OK, deleted",
        "id": "135694494"
      }
    }
  }
}

Delete one or more notifications in your company.

HTTP Request

deletehttps://rest.tsheets.com/api/v1/notifications

Parameters

ids
required
Int Comma separated list of notification ids you'd like to delete. Note that notifications are actually deleted, not archived.

Status Codes

Each notification that is deleted will come back with a _status_code and _status_message that will indicate whether the notification was deleted successfully. If there was a problem deleting a notification, there may also be an additional field, _status_extra, which will contain more details about the failure.

200 OK. Notification was deleted successfully.
404 Not Found. Notification either has never existed or has already been delivered or deleted.
417 Expectation Failed. Something went wrong for this notification. See the _status_extra value for more detail.

Projects

The Project Object

Example

{
  "id": 527093,
  "jobcode_id": 6386831,
  "parent_jobcode_id": 6386823,
  "name": "Valley St. Landscaping",
  "status": "in_progress",
  "description": "Letterpress 90's kitsch, tattooed kogi chambray gochujang readymade gastropub selfies.",
  "start_date": "2019-07-01T00:00:00+00:00",
  "due_date": "2019-07-19T00:00:00+00:00",
  "completed_date": "",
  "active": true,
  "last_modified": "2019-06-25T16:06:03+00:00",
  "created": "2019-05-09T18:46:44+00:00",
  "linked_objects": {
      "notes_read_times": []
  }
}

The following is a list of the properties that belong to a project object, and a description of each.

A jobcode is associated with each project for time tracking. When creating a project, you can provide your own jobcode or omit the jobcode_id field to have one created for you. If a jobcode is provided it cannot have children or already be mapped to a project.

A project must be created under a parent jobcode (or customer) and cannot be a project itself.

id
read-only
Int ID of this project.
name
read-write
String Name of project. Limited to 64 characters.
jobcode_id
read/write-once
Int The jobcode that represents the project for time tracking.
parent_jobcode_id
read/write-once
Int Id of the project jobcode's parent. 0 if it's top-level.
description
read-write
String Description text associated with project. Limited to 300 characters.
status
read-write
String Status of project. Allowed values include: not_started, in_progress, complete.
start_date
read-write
String YYYY-MM-DD formatted date string. Must be before due date if one is defined.
due_date
read-write
String YYYY-MM-DD formatted date string. Must be after the start date if one is defined.
completed_date
read-write
String YYYY-MM-DD formatted date string. Must be after the start date if one is defined.
active
read-write
Boolean True or false. If false, this project is considered deleted.
last_modified
read
String Date/time when this project was last modified, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm).
created
read
String Date/time when this project was created, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm).
linked_objects
read-write
Object A key/value map of all the objects linked to this project and the corresponding object ids.

Retrieve Projects

Example: Retrieve a list of projects based on the provided filter.

Request

curl "https://rest.tsheets.com/api/v1/projects" \
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/projects");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/projects")
Dim request = New RestRequest(Method.[GET])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/projects")
  .get()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/projects",
  "method": "GET",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'GET',
  url: 'https://rest.tsheets.com/api/v1/projects',
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/projects');
$request->setMethod(HTTP_METH_GET);

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/projects")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/projects"

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/projects"

  req, _ := http.NewRequest("GET", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/projects")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest, completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/projects"; 

$client->GET($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "projects": {
      "527093": {
        "id": 527093,
        "jobcode_id": 6386831,
        "parent_jobcode_id": 6386823,
        "name": "MVP",
        "status": "in_progress",
        "description": "",
        "start_date": "2019-07-01T00:00:00+00:00",
        "due_date": "2019-07-19T00:00:00+00:00",
        "completed_date": "",
        "active": true,
        "last_modified": "2019-07-29T16:33:37+00:00",
        "created": "2019-05-09T18:46:44+00:00",
        "linked_objects": {
            "notes_read_times": []
        }
      },
      "532863": {
        "id": 532863,
        "jobcode_id": 6453991,
        "parent_jobcode_id": 6386823,
        "name": "Space Cat",
        "status": "in_progress",
        "description": "",
        "start_date": "",
        "due_date": "",
        "completed_date": "",
        "active": true,
        "last_modified": "2019-06-25T16:06:04+00:00",
        "created": "2019-05-14T20:26:45+00:00",
        "linked_objects": {
            "notes_read_times": []
        }
      }
    }
  },
  "supplemental_data": {
    "jobcodes": {
      "6386831": {
        "id": 6386831,
        "active": true,
        "parent_id": 6386823,
        "assigned_to_all": true,
        "type": "regular",
        "billable": false,
        "billable_rate": 0,
        "short_code": "",
        "name": "MVP",
        "created": "2019-05-09T18:46:44+00:00",
        "last_modified": "2019-07-29T17:49:52+00:00",
        "has_children": false,
        "required_customfields": [],
        "filtered_customfielditems": {
          "60138": [
            5406977,
            5406979
          ],
          "225841": [
            1944187
          ]
        },
        "locations": []
      },
      "6453991": {
        "id": 6453991,
        "active": true,
        "parent_id": 6386823,
        "assigned_to_all": true,
        "type": "regular",
        "billable": false,
        "billable_rate": 0,
        "short_code": "",
        "name": "Space Cat",
        "created": "2019-05-14T20:26:45+00:00",
        "last_modified": "2019-07-09T20:18:22+00:00",
        "has_children": false,
        "required_customfields": [],
        "filtered_customfielditems": {
          "225841": [
            1273285
          ]
        },
        "locations": []
      },
      "6386823": {
        "id": 6386823,
        "active": true,
        "parent_id": 0,
        "assigned_to_all": true,
        "type": "regular",
        "billable": false,
        "billable_rate": 0,
        "short_code": "",
        "name": "The Best, Inc.",
        "created": "2019-05-09T18:43:13+00:00",
        "last_modified": "2019-05-09T18:43:13+00:00",
        "has_children": true,
        "required_customfields": [],
        "filtered_customfielditems": {},
        "locations": []
      }
    }
  },
  "more": false
}

Retrieves a list of projects, with optional filters to narrow down the results.

HTTP Request

gethttps://rest.tsheets.com/api/v1/projects

Filter Parameters

ids
optional
Int Comma-separated list of project ids.
jobcode_ids
optional
Int Comma-separated list of jobcode ids associated with a project.
parent_jobcode_id
optional
Int Id of a project jobcode's parent to use for filtering. Only projects whose jobcode has a parent_id set to this value will be returned.
name
optional
String * will be interpreted as a wild card. Starts matching from the beginning of the string.
active
optional
String 'yes', 'no', or 'both'. Default is 'yes'.
by_jobcode_assignment
optional
Boolean true or false. If specified, only projects with a jobcode_id the user is assigned to will be returned.

Create Projects

Example: Create a new project.

Request Body

{
  "data": [{
    "name": "Xmas Party 2019",
    "parent_jobcode_id": 6386823,
    "description": "This is the project to track all party prep.",
    "start_date": "2019-11-05T00:00:00+00:00",
    "due_date": "2019-12-15T00:00:00+00:00"
  }]
}


Request

curl -X POST \
  https://rest.tsheets.com/api/v1/projects \
  -H 'Authorization: Bearer <TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '<REQUEST BODY>'
var client = new RestClient("https://rest.tsheets.com/api/v1/projects");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <TOKEN>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "<REQUEST BODY>", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/projects")
Dim request = New RestRequest(Method.POST)
request.AddHeader("Authorization", "Bearer <TOKEN>")
request.AddHeader("Content-Type", "application/json")
request.AddParameter("application/json", "<REQUEST BODY>", ParameterType.RequestBody);
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<REQUEST BODY>");
Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/projects")
  .post(body)
  .addHeader("Authorization", "Bearer <TOKEN>")
  .addHeader("Content-Type", "application/json")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/projects",
  "method": "POST",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
    "Content-Type", "application/json",
  },
  "processData": false,
  "data": "<REQUEST BODY>"
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'POST',
  url: 'https://rest.tsheets.com/api/v1/projects',
  headers: 
  { 
     'Authorization': 'Bearer <TOKEN>',
     'Content-Type': 'application/json',
  },
  body: '<REQUEST BODY>',
  json: true };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/projects');
$request->setMethod(HTTP_METH_POST);

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
  'Content-Type' => 'application/json',
));

$request->setBody('<REQUEST BODY>');

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/projects")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <TOKEN>',
request["Content-Type"] = 'application/json',
request.body = "<REQUEST BODY>"

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/projects"

payload = "<REQUEST BODY>"
headers = {
    'Authorization': 'Bearer <TOKEN>',
    'Content-Type': 'application/json',
    }

response = requests.request("POST", url, data=payload, headers=headers)

print(response.text)
package main

import (
  "fmt"
  "strings"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/projects"

  payload := strings.NewReader("<REQUEST BODY>")

  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, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))

}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
   "Content-Type": "application/json",
]
let parameters = <REQUEST BODY> as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/projects")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest,
  completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');
$client->addHeader('Content-Type', 'application/json');

$req = '<REQUEST BODY>';

$url="https://rest.tsheets.com/api/v1/projects"; 

$client->POST($url, $req);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "projects": {
      "1": {
        "_status_code": 200,
        "_status_message": "Created",
        "id": 527093,
        "jobcode_id": 6386831,
        "parent_jobcode_id": 6386823,
        "name": "Xmas Party 2019",
        "status": "not_started",
        "description": "This is the project to track all party prep.",
        "start_date": "2019-11-05T00:00:00+00:00",
        "due_date": "2019-12-15T00:00:00+00:00",
        "completed_date": "",
        "active": true,
        "last_modified": "2019-07-29T16:33:37+00:00",
        "created": "2019-05-09T18:46:44+00:00",
        "linked_objects": {
            "notes_read_times": []
        }
      }
    }
  },
  "supplemental_data": {
    "jobcodes": {
      "6386823": {
        "id": 6386823,
        "active": true,
        "parent_id": 0,
        "assigned_to_all": true,
        "type": "regular",
        "billable": false,
        "billable_rate": 0,
        "short_code": "",
        "name": "The Best, Inc.",
        "created": "2019-05-09T18:43:13+00:00",
        "last_modified": "2019-05-09T18:43:13+00:00",
        "has_children": true,
        "required_customfields": [],
        "filtered_customfielditems": {},
        "locations": [],
        "geofence_config_id": null,
        "project_id": 0
      },
      "6386831": {
        "id": 6386831,
        "active": true,
        "parent_id": 6386823,
        "assigned_to_all": true,
        "type": "regular",
        "billable": false,
        "billable_rate": 0,
        "short_code": "",
        "name": "Xmas Party 2019",
        "created": "2019-05-09T18:46:44+00:00",
        "last_modified": "2019-07-29T17:49:52+00:00",
        "has_children": false,
        "required_customfields": [],
        "filtered_customfielditems": [],
        "locations": [],
        "geofence_config_id": null,
        "project_id": 527093
      }
    }
  }
}

Example: Create a new project w/ an existing jobcode.

Request Body

{
  "data": [{
    "jobcode_id": 6386831,
    "description": "This is the project to track all party prep.",
    "start_date": "2019-11-05T00:00:00+00:00",
    "due_date": "2019-12-15T00:00:00+00:00"
  }]
}


Request

curl -X POST \
  https://rest.tsheets.com/api/v1/projects \
  -H 'Authorization: Bearer <TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '<REQUEST BODY>'
var client = new RestClient("https://rest.tsheets.com/api/v1/projects");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <TOKEN>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "<REQUEST BODY>", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/projects")
Dim request = New RestRequest(Method.POST)
request.AddHeader("Authorization", "Bearer <TOKEN>")
request.AddHeader("Content-Type", "application/json")
request.AddParameter("application/json", "<REQUEST BODY>", ParameterType.RequestBody);
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<REQUEST BODY>");
Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/projects")
  .post(body)
  .addHeader("Authorization", "Bearer <TOKEN>")
  .addHeader("Content-Type", "application/json")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/projects",
  "method": "POST",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
    "Content-Type", "application/json",
  },
  "processData": false,
  "data": "<REQUEST BODY>"
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'POST',
  url: 'https://rest.tsheets.com/api/v1/projects',
  headers: 
  { 
     'Authorization': 'Bearer <TOKEN>',
     'Content-Type': 'application/json',
  },
  body: '<REQUEST BODY>',
  json: true };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/projects');
$request->setMethod(HTTP_METH_POST);

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
  'Content-Type' => 'application/json',
));

$request->setBody('<REQUEST BODY>');

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/projects")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <TOKEN>',
request["Content-Type"] = 'application/json',
request.body = "<REQUEST BODY>"

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/projects"

payload = "<REQUEST BODY>"
headers = {
    'Authorization': 'Bearer <TOKEN>',
    'Content-Type': 'application/json',
    }

response = requests.request("POST", url, data=payload, headers=headers)

print(response.text)
package main

import (
  "fmt"
  "strings"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/projects"

  payload := strings.NewReader("<REQUEST BODY>")

  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, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))

}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
   "Content-Type": "application/json",
]
let parameters = <REQUEST BODY> as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/projects")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest,
  completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');
$client->addHeader('Content-Type', 'application/json');

$req = '<REQUEST BODY>';

$url="https://rest.tsheets.com/api/v1/projects"; 

$client->POST($url, $req);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "projects": {
      "1": {
        "_status_code": 200,
        "_status_message": "Created",
        "id": 527093,
        "jobcode_id": 6386831,
        "parent_jobcode_id": 6386823,
        "name": "Xmas Party 2019",
        "status": "not_started",
        "description": "This is the project to track all party prep.",
        "start_date": "2019-11-05T00:00:00+00:00",
        "due_date": "2019-12-15T00:00:00+00:00",
        "completed_date": "",
        "active": true,
        "last_modified": "2019-07-29T16:33:37+00:00",
        "created": "2019-05-09T18:46:44+00:00",
        "linked_objects": {
            "notes_read_times": []
        }
      }
    }
  },
  "supplemental_data": {
    "jobcodes": {
      "6386823": {
        "id": 6386823,
        "active": true,
        "parent_id": 0,
        "assigned_to_all": true,
        "type": "regular",
        "billable": false,
        "billable_rate": 0,
        "short_code": "",
        "name": "The Best, Inc.",
        "created": "2019-05-09T18:43:13+00:00",
        "last_modified": "2019-05-09T18:43:13+00:00",
        "has_children": true,
        "required_customfields": [],
        "filtered_customfielditems": {},
        "locations": [],
        "geofence_config_id": null,
        "project_id": 0
      },
      "6386831": {
        "id": 6386831,
        "active": true,
        "parent_id": 6386823,
        "assigned_to_all": true,
        "type": "regular",
        "billable": false,
        "billable_rate": 0,
        "short_code": "",
        "name": "Xmas Party 2019",
        "created": "2019-05-09T18:46:44+00:00",
        "last_modified": "2019-07-29T17:49:52+00:00",
        "has_children": false,
        "required_customfields": [],
        "filtered_customfielditems": [],
        "locations": [],
        "geofence_config_id": null,
        "project_id": 527093
      }
    }
  }
}

Create one or more TSheets Projects.

HTTP Request

posthttps://rest.tsheets.com/api/v1/projects

Properties

Pass an array of Projects objects as the value to a 'data' property (see example).

name
required
String Name of project, ignored if job_code_id is provided. Limited to 64 characters.
jobcode_id
optional
Int The jobcode that represents the project, used for tracking time against the project. If an id is provided on create we use the jobcode provided, otherwise a new jobcode is automatically generated. The provided jobcode must have no children and cannot already be mapped to an existing project.
parent_jobcode_id
optional
Int This jobcode is set as the parent of the project's jobcode. This jobcode cannot be already tied to an existing project. If the jobcode_id is also provided on POST its parent must match this id.
description
optional
String Description text associated with project. Limited to 300 characters.
status
optional
String Status of project. Allowed values include: 'not_started', 'in_progress', 'complete'.
start_date
optional
String YYYY-MM-DD formatted date string. Must be before due date if one is defined.
due_date
optional
String YYYY-MM-DD formatted date string. Must be after the start date if one is defined.
completed_date
optional
String YYYY-MM-DD formatted date string. Is automatically set when status is changed to complete, can also be set manually.

For a full list of the properties that may be set on a project, see The Project Object.

Status Codes

Each project that is created will come back with a _status_code and _status_message that will indicate whether the project was created successfully. If there was a problem creating a project, there may also be an additional field, _status_extra, which will contain more details about the failure.

200 OK. Project was created successfully.
417 Expectation Failed. Something was wrong or missing with the properties supplied for this project. See the _status_extra value for more detail.

Update Projects

Example: Edit a project.

Request Body

{
  "data": [{
    "id": 527093,
    "status": "complete"
  }]
}

Request

curl -X PUT \
  https://rest.tsheets.com/api/v1/projects \
  -H 'Authorization: Bearer <TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '<REQUEST BODY>'
var client = new RestClient("https://rest.tsheets.com/api/v1/projects");
var request = new RestRequest(Method.PUT);
request.AddHeader("Authorization", "Bearer <TOKEN>");
request.AddHeader("Content-Type", "application/json");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/projects")
Dim request = New RestRequest(Method.PUT)
request.AddHeader("Authorization", "Bearer <TOKEN>")
request.AddHeader("Content-Type", "application/json")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<REQUEST BODY>");
Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/projects")
  .put(body)
  .addHeader("Authorization", "Bearer <TOKEN>")
  .addHeader("Content-Type", "application/json")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/projects",
  "method": "PUT",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
    "Content-Type", "application/json",
  },
  "processData": false,
  "data": "<REQUEST BODY>"
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'PUT',
  url: 'https://rest.tsheets.com/api/v1/projects',
  headers: 
  { 
     'Authorization': 'Bearer <TOKEN>',
     'Content-Type': 'application/json',
  },
  body: '<REQUEST BODY>',
  json: true };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/projects');
$request->setMethod(HTTP_METH_PUT);

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
  'Content-Type' => 'application/json',
));

$request->setBody('<REQUEST BODY>');

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/projects")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <TOKEN>',
request["Content-Type"] = 'application/json',
request.body = "<REQUEST BODY>"

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/projects"

payload = "<REQUEST BODY>"
headers = {
    'Authorization': 'Bearer <TOKEN>',
    'Content-Type': 'application/json',
    }

response = requests.request("PUT", url, data=payload, headers=headers)

print(response.text)
package main

import (
  "fmt"
  "strings"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/projects"

  payload := strings.NewReader("<REQUEST BODY>")

  req, _ := http.NewRequest("PUT", 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, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))

}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
   "Content-Type": "application/json",
]
let parameters = <REQUEST BODY> as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(
  url: NSURL(string: "http://rest.tsheets.com/api/v1/projects")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "PUT"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest,
  completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');
$client->addHeader('Content-Type', 'application/json');

$req = '<REQUEST BODY>';

$url="http://rest.tsheets.com/api/v1/projects"; 

$client->PUT($url, $req);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "projects": {
      "1": {
        "_status_code": 200,
        "_status_message": "Updated",
        "id": 527093,
        "jobcode_id": 6386831,
        "parent_jobcode_id": 6386823,
        "name": "Xmas Party 2019",
        "status": "complete",
        "description": "This is the project to track all party prep.",
        "start_date": "2019-11-05T00:00:00+00:00",
        "due_date": "2019-12-15T00:00:00+00:00",
        "completed_date": "2019-12-14T00:00:00+00:00",
        "active": true,
        "last_modified": "2019-07-29T16:33:37+00:00",
        "created": "2019-05-09T18:46:44+00:00",
        "linked_objects": {
            "notes_read_times": []
        }
      }
    }
  },
  "supplemental_data": {
    "jobcodes": {
      "6386831": {
        "id": 6386831,
        "active": false,
        "parent_id": 6386823,
        "assigned_to_all": true,
        "type": "regular",
        "billable": false,
        "billable_rate": 0,
        "short_code": "",
        "name": "Xmas Party 2019",
        "created": "2019-05-09T18:46:44+00:00",
        "last_modified": "2019-07-29T17:49:52+00:00",
        "has_children": false,
        "required_customfields": [],
        "filtered_customfielditems": [],
        "locations": [],
        "geofence_config_id": null,
        "project_id": 527093
      },
      "6386823": {
        "id": 6386823,
        "active": true,
        "parent_id": 0,
        "assigned_to_all": true,
        "type": "regular",
        "billable": false,
        "billable_rate": 0,
        "short_code": "",
        "name": "The Best, Inc.",
        "created": "2019-05-09T18:43:13+00:00",
        "last_modified": "2019-05-09T18:43:13+00:00",
        "has_children": true,
        "required_customfields": [],
        "filtered_customfielditems": {},
        "locations": [],
        "geofence_config_id": null,
        "project_id": 0
      }
    }
  }
}


Edit one or more TSheets Projects.

HTTP Request

puthttps://rest.tsheets.com/api/v1/projects

Properties

Pass an array of Projects objects as the value to a 'data' property (see example).

name
required
String Name of project. When updated this will also update the name of the related jobcode. Limited to 64 characters.
description
optional
String Description text associated with project. Limited to 300 characters.
status
optional
String Status of project. Allowed values include: 'not_started', 'in_progress', 'complete'. If status is set to complete the completed date is also set and the related jobcode is archived.
start_date
optional
String YYYY-MM-DD formatted date string. Must be before due date if one is defined.
due_date
optional
String YYYY-MM-DD formatted date string. Must be after the start date if one is defined.
completed_date
optional
String YYYY-MM-DD formatted date string. Is automatically set when status is changed to complete, can also be set manually.

For a full list of the properties that may be set on a project, see The Project Object.

Status Codes

Each project that is edited will come back with a _status_code and _status_message that will indicate whether the project was edited successfully. If there was a problem creating a project, there may also be an additional field, _status_extra, which will contain more details about the failure.

200 OK. Project was edited successfully.
417 Expectation Failed. Something was wrong or missing with the properties supplied for this project. See the _status_extra value for more detail.

Project Activities

The Project Activity Object

Example

{
    "id": 527093,
    "active": true,
    "user_id": 453,
    "project_id": 6386831,
    "activity_type": "clock_in",
    "last_modified": "2019-06-25T16:06:03+00:00",
    "unread_replies_count": 0,
    "following": true,
    "created": "2019-05-09T18:46:44+00:00",
    "project_activity_metadata": [4588975,4588974],
    "linked_objects" : {
      "project_notes": [588972,588973]
    }
}

Following is a list of the properties that belong to a project_activity object, and a description of each.

id
read-only
Int ID of this project_activity.
active
read-write
Boolean true or false. If false, this project activity is considered archived.
user_id
read-only
Int ID of the associated user.
project_id
read-only
Int ID of the associated project.
activity_type
read-write
String Options - 'clock_in', 'clock_out', 'note', 'attachment', 'project_update', 'location_update', 'estimate_item_added', 'estimate_item_removed', 'estimate_item_updated', 'assignment', 'unassignment'
last_modified
read-only
String Date/time when this project activity was last modified, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm).
created
read-only
String Date/time when this project activity was created, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm)
linked_objects
read-write
Object A key/value map of all the objects linked to this project activity and the corresponding object ids.

Activity Types

Following is a list of valid activity_type values.

activity_type Description
clock_in One or more employees have clocked into a Project task.
clock_out One or more employees have clocked out of a Project task.
note A team member assigned to the Project has added a Note to the Project.
attachment A team member assigned to the Project has uploaded an attachment to the Project.
project_update A team member assigned to the Project has updated properties of the Project.
project_created A team member assigned to the Project has created the Project.
location_update A team member assigned to the Project is on the clock in a given Location.
estimate_item_added An Estimate Item has been added to the Project.
estimate_item_removed An Estimate Item has been removed from the Project.
estimate_item_updated An Estimate Item has been updated for the Project.
assignment One or more team members have been assigned to the Project.
unassignment One or more team members have been unassigned from the Project.

Retrieve Project Activity objects

Example: Retrieve a list of project activities having the given project_id.

Request

curl "https://rest.tsheets.com/api/v1/project_activities?project_id=1234" \
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/project_activities?project_id=1234");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/project_activities?project_id=1234")
Dim request = New RestRequest(Method.[GET])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/project_activities?project_id=1234")
  .get()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/project_activities?project_id=1234",
  "method": "GET",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'GET',
  url: 'https://rest.tsheets.com/api/v1/project_activities',
  qs: {
    project_id: '1234',
  },
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/project_activities');
$request->setMethod(HTTP_METH_GET);

$request->setQueryData(array(
  'project_id' => '1234',
));

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/project_activities?project_id=1234")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/project_activities"

querystring = {
  "project_id":"1234",
}

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/project_activities?project_id=1234"

  req, _ := http.NewRequest("GET", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/project_activities?project_id=1234")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest, completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/project_activities?project_id=1234"; 

$client->GET($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "project_activities": {
      "65306": {
        "id": 65306,
        "user_id": 2589531,
        "activity_type": "note",
        "active": true,
        "project_id": 3989532,
        "created": "2018-03-09T18:26:57+00:00",
        "last_modified": "2018-03-15T16:51:14+00:00",
        "project_activity_metadata": [],
        "linked_objects": {
          "project_notes" : [9823457]
        },
      }
    },
    "supplemental_data": {
      "users": {
        "2589531": {
          "id": 2589531,
          "first_name": "Jeff",
          "last_name": "Olden",
          "display_name": "",
          "group_id": 0,
          "active": true,
          "employee_number": 0,
          "salaried": false,
          "exempt": false,
          "username": "admin",
          "email": "admin@example.com",
          "email_verified": false,
          "payroll_id": "",
          "hire_date": "0000-00-00",
          "term_date": "0000-00-00",
          "last_modified": "2018-03-15T23:09:27+00:00",
          "last_active": "2022-05-09T21:36:43+00:00",
          "created": "2018-03-15T15:50:50+00:00",
          "client_url": "api_sample_output",
          "company_name": "API Sample Output Company",
          "profile_image_url": "https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61",
          "pronouns": "",
          "mobile_number": "",
          "pto_balances": {
              "701818256": 0,
              "701818258": 0,
              "701818260": 0
          },
          "submitted_to": "2000-01-01",
          "approved_to": "2000-01-01",
          "manager_of_group_ids": [],
          "require_password_change": false,
          "pay_rate": 0,
          "pay_interval": "hour",
          "permissions": {
              "admin": true,
              "mobile": true,
              "status_box": true,
              "reports": true,
              "manage_timesheets": true,
              "manage_authorization": true,
              "manage_users": true,
              "manage_my_timesheets": true,
              "manage_jobcodes": true,
              "pin_login": true,
              "approve_timesheets": true,
              "manage_schedules": false,
              "external_access": false,
              "manage_my_schedule": false,
              "manage_company_schedules": false,
              "view_company_schedules": false,
              "view_group_schedules": false,
              "manage_no_schedules": false,
              "view_my_schedules": false,
              "view_projects": false,
              "manage_projects": true,
              "time_tracking": true
          },
          "customfields": ""
        }
      },
      "projects": {
        "3989532": {
          "id": 3989532,
          "job_code_id": 3541,
          "parent_job_code_id": 345,
          "name": "Super Rad Project",
          "status": "started",
          "description": "Best project of the year, for sure",
          "start_date": "2018-04-15T15:50:50+00:00",
          "due_date": "2018-04-17T15:50:50+00:00",
          "completed_date": "2018-04-17T15:50:50+00:00",
          "active": true,
          "last_modified": "2018-03-15T23:09:27+00:00",
          "created": "2018-03-15T15:50:50+00:00",
          "linked_objects": {
              "notes_read_times": [
                  159834
              ]
          }
        }
      },
      "project_notes": {
        "9823457" : {
          "id": 9823457,
          "note": "The Project is progressing well",
          "user_id": 2589531,
          "active": true,
          "project_id": 3989532,
          "created": "2019-08-13T17:19:44+00:00",
          "last_modified": "2019-08-13T17:19:44+00:00",
          "linked_objects": { "project_activities": [65306] }
        }
      }
    },
    "more": false
  }

Example: Retrieve a list of project activities having the given project_id and having one of the given activity types.

Request

curl "https://rest.tsheets.com/api/v1/project_activities?project_id=1234&activity_types=clock_in,clock_out" \
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/project_activities?project_id=1234&activity_types=clock_in,clock_out");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/project_activities?project_id=1234&activity_types=clock_in,clock_out")
Dim request = New RestRequest(Method.[GET])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/project_activities?project_id=1234&activity_types=clock_in,clock_out")
  .get()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/project_activities?project_id=1234&activity_types=clock_in,clock_out",
  "method": "GET",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'GET',
  url: 'https://rest.tsheets.com/api/v1/project_activities',
  qs: {
    project_id: '1234',
    activity_types: 'clock_in,clock_out',
  },
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/project_activities');
$request->setMethod(HTTP_METH_GET);

$request->setQueryData(array(
  'project_id' => '1234',
  'activity_types' => 'clock_in,clock_out',
));

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/project_activities?project_id=1234&activity_types=clock_in,clock_out")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/project_activities"

querystring = {
  "project_id":"1234",
  "activity_types":"clock_in,clock_out",
}

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/project_activities?project_id=1234&activity_types=clock_in,clock_out"

  req, _ := http.NewRequest("GET", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/project_activities?project_id=1234&activity_types=clock_in,clock_out")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest, completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/project_activities?project_id=1234&activity_types=clock_in,clock_out"; 

$client->GET($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "project_activities": {
      "65306": {
        "id": 65306,
        "user_id": 2589531,
        "activity_type": "note",
        "active": true,
        "project_id": 3989532,
        "created": "2018-03-09T18:26:57+00:00",
        "last_modified": "2018-03-15T16:51:14+00:00",
        "project_activity_metadata": [],
        "linked_objects": {
          "project_notes" : [9823457]
        },
      }
    },
    "supplemental_data": {
      "users": {
        "2589531": {
          "id": 2589531,
          "first_name": "Jeff",
          "last_name": "Olden",
          "display_name": "",
          "group_id": 0,
          "active": true,
          "employee_number": 0,
          "salaried": false,
          "exempt": false,
          "username": "admin",
          "email": "admin@example.com",
          "email_verified": false,
          "payroll_id": "",
          "hire_date": "0000-00-00",
          "term_date": "0000-00-00",
          "last_modified": "2018-03-15T23:09:27+00:00",
          "last_active": "2022-05-09T21:36:43+00:00",
          "created": "2018-03-15T15:50:50+00:00",
          "client_url": "api_sample_output",
          "company_name": "API Sample Output Company",
          "profile_image_url": "https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61",
          "pronouns": "",
          "mobile_number": "",
          "pto_balances": {
              "701818256": 0,
              "701818258": 0,
              "701818260": 0
          },
          "submitted_to": "2000-01-01",
          "approved_to": "2000-01-01",
          "manager_of_group_ids": [],
          "require_password_change": false,
          "pay_rate": 0,
          "pay_interval": "hour",
          "permissions": {
              "admin": true,
              "mobile": true,
              "status_box": true,
              "reports": true,
              "manage_timesheets": true,
              "manage_authorization": true,
              "manage_users": true,
              "manage_my_timesheets": true,
              "manage_jobcodes": true,
              "pin_login": true,
              "approve_timesheets": true,
              "manage_schedules": false,
              "external_access": false,
              "manage_my_schedule": false,
              "manage_company_schedules": false,
              "view_company_schedules": false,
              "view_group_schedules": false,
              "manage_no_schedules": false,
              "view_my_schedules": false,
              "view_projects": false,
              "manage_projects": true,
              "time_tracking": true
          },
          "customfields": ""
        }
      },
      "projects": {
        "3989532": {
          "id": 3989532,
          "job_code_id": 3541,
          "parent_job_code_id": 345,
          "name": "Super Rad Project",
          "status": "started",
          "description": "Best project of the year, for sure",
          "start_date": "2018-04-15T15:50:50+00:00",
          "due_date": "2018-04-17T15:50:50+00:00",
          "completed_date": "2018-04-17T15:50:50+00:00",
          "active": true,
          "last_modified": "2018-03-15T23:09:27+00:00",
          "created": "2018-03-15T15:50:50+00:00",
          "linked_objects": {
              "notes_read_times": [
                  159834
              ]
          }
        }
      },
      "project_notes": {
        "9823457" : {
          "id": 9823457,
          "note": "The Project is progressing well",
          "user_id": 2589531,
          "active": true,
          "project_id": 3989532,
          "created": "2019-08-13T17:19:44+00:00",
          "last_modified": "2019-08-13T17:19:44+00:00",
          "linked_objects": { "project_activities": [65306] }
        }
      }
    },
    "more": false
  }

Retrieves a list of all project activities associated with a project, with optional filters to narrow down the results.

HTTP Request

gethttps://rest.tsheets.com/api/v1/project_activities

Filter Parameters

project_id
required (unless ids is set)
Int ID for one project you’d like to filter on. Only project_activity objects with a project_id set to this will be returned.
ids
required (unless project_id is set)
String Comma separated list of one or more project_activity ids you would like to filter on. Only project_activity objects with an id set to one of these values will be returned. If omitted, all project_activity records matching other specified filters are returned.
activity_types
optional
String Comma separated list of one or more activity types you would like to filter on. Only with a name set to one of these values will be returned. If omitted, all project_activity objects matching other specified filters are returned.
modified_before
optional
String Only project activities modified before this date/time will be returned, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm)
modified_since
optional
String Only project activities modified since this date/time will be returned, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm)
supplemental_data
optional
String 'yes' or 'no'. Default is 'yes'. Indicates whether supplemental data should be returned.
per_page
optional
Int Deprecated. Use limit for new code.
Represents how many results you'd like to retrieve per request. Default is 50. Max is 50.
If a value over 50 is provided, it is ignored, and the max is used.
limit
optional
Int Represents how many results you'd like to retrieve per request. Default is 200. Max is 200.
If present, this value must be: an integer, greater than zero, and not greater than 200.
Setting limit less than 1 or greater than 200 will result in an error.
page
optional
Int Represents the page of results you would like to retrieve. Default is 1.
max_id
optional
Int Only project activities with an ID less than or equal to this will be returned.

Project Activity Read Times

The Project Activity Read Time Object

Example

{
    "id": 527093,
    "user_id": 234856
    "project_id": 6386831,
    "latest_read_time": "2019-05-09T18:46:44+00:00"
}

Following is a list of the properties that belong to a project_activity_read_time object, and a description of each.

id
read-only
Int ID of this project_activity_read_time.
user_id
read-write
Int ID of the associated user. Only the current user id is allowed
project_id
read-write
Int ID of the associated project.
latest_read_time
read-only
String Date/time when this project activity was last read, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm).

Retrieve Project Activity Read Times

Example: Retrieve all project_activity_read_times for a user.

Request

curl "https://rest.tsheets.com/api/v1/project_activity_read_times" \
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/project_activity_read_times");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/project_activity_read_times")
Dim request = New RestRequest(Method.[GET])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/project_activity_read_times")
  .get()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/project_activity_read_times",
  "method": "GET",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'GET',
  url: 'https://rest.tsheets.com/api/v1/project_activity_read_times',
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/project_activity_read_times');
$request->setMethod(HTTP_METH_GET);

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/project_activity_read_times")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/project_activity_read_times"

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/project_activity_read_times"

  req, _ := http.NewRequest("GET", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/project_activity_read_times")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest, completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/project_activity_read_times"; 

$client->GET($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "project_activity_read_times": {
      "10001": {
        "id": 10001,
        "project_id": 30001,
        "user_id": 20001,
        "latest_read_time": "2020-01-01T00:00:00+00:00"
      },
      "10002": {
        "id": 10002,
        "project_id": 30002,
        "user_id": 20001,
        "latest_read_time": "2020-01-05T00:00:00+00:00"
      },
    }
  },
  "supplemental_data": {
    "projects": {
      "30001": {
        "id": 30001,
        "jobcode_id": 50001,
        "parent_jobcode_id": 0,
        "name": "Test Project",
        "status": "in_progress",
        "description": "Test Project for Docs",
        "start_date": "",
        "due_date": "",
        "completed_date": "",
        "active": true,
        "last_modified": "2019-11-21T18:42:06+00:00",
        "created": "2019-11-21T18:42:06+00:00",
        "linked_objects": {
            "notes_read_times": [
                159834
            ]
        }
      },
      {
        "id": 30002,
        "jobcode_id": 50002,
        "name": "Test Project 2",
        "status": "in_progress",
        "description": "Test Project 2 for Docs",
        "start_date": "",
        "due_date": "",
        "completed_date": "",
        "active": true,
        "last_modified": "2019-11-21T18:42:06+00:00",
        "created": "2019-11-21T18:42:06+00:00",
        "linked_objects": {
            "notes_read_times": [
                160538
            ]
        }
      }
    }
  },
  "more": false
}

Example: Retrieve a list of project_activity_read_times given list of ids. If ids is omitted all project_activity_read_times for the current user are returned.

Request

curl "https://rest.tsheets.com/api/v1/project_activity_read_times?ids=10001" \
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/project_activity_read_times?ids=10001");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/project_activity_read_times?ids=10001")
Dim request = New RestRequest(Method.[GET])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/project_activity_read_times?ids=10001")
  .get()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/project_activity_read_times?ids=10001",
  "method": "GET",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'GET',
  url: 'https://rest.tsheets.com/api/v1/project_activity_read_times',
  qs: {
    ids: '10001',
  },
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/project_activity_read_times');
$request->setMethod(HTTP_METH_GET);

$request->setQueryData(array(
  'ids' => '10001',
));

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/project_activity_read_times?ids=10001")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/project_activity_read_times"

querystring = {
  "ids":"10001",
}

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/project_activity_read_times?ids=10001"

  req, _ := http.NewRequest("GET", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/project_activity_read_times?ids=10001")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest, completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/project_activity_read_times?ids=10001"; 

$client->GET($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "project_activity_read_times": {
      "10001": {
        "id": 10001,
        "project_id": 30001,
        "user_id": 20001,
        "latest_read_time": "2020-01-01T00:00:00+00:00"
      }
    }
  },
  "supplemental_data": {
    "projects": {
      "30001": {
        "id": 30001,
        "jobcode_id": 50001,
        "parent_jobcode_id": 0,
        "name": "Test Project",
        "status": "in_progress",
        "description": "Test Project for Docs",
        "start_date": "",
        "due_date": "",
        "completed_date": "",
        "active": true,
        "last_modified": "2019-11-21T18:42:06+00:00",
        "created": "2019-11-21T18:42:06+00:00",
        "linked_objects": {
            "notes_read_times": [
                171016
            ]
        }
      }
    }
  },
  "more": false
}

Retrieves the project_activity_read_time associated with a project, with optional filters to narrow down the results.

HTTP Request

gethttps://rest.tsheets.com/api/v1/project_activity_read_times

Filter Parameters

ids
optional
Int Comma separated list of one or more project ids you would like to filter on. Only projects with an id set to one of these values will be returned. If omitted, all project_activity_read_times matching other specified filters are returned.
modified_before
optional
String Only project_activity_read_times modified before this date/time will be returned, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm)
modified_since
optional
String Only project_activity_read_times modified since this date/time will be returned, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm)
supplemental_data
optional
String 'yes' or 'no'. Default is 'yes'. Indicates whether supplemental data should be returned.
per_page
optional
Int Deprecated. Use limit for new code.
Represents how many results you'd like to retrieve per request. Default is 50. Max is 50.
If a value over 50 is provided, it is ignored, and the max is used.
limit
optional
Int Represents how many results you'd like to retrieve per request. Default is 200. Max is 200.
If present, this value must be: an integer, greater than zero, and not greater than 200.
Setting limit less than 1 or greater than 200 will result in an error.
page
optional
Int Represents the page of results you would like to retrieve. Default is 1.

Update Project Activity Read Time

Example: Last time a user read activity feed for a particular project.

Request Body

{
  "data": [
    {
      "project_id": 30001
    },
    {
      "project_id": 30002
    }
  ]
}


Request

curl -X POST \
  https://rest.tsheets.com/api/v1/project_activity_read_times \
  -H 'Authorization: Bearer <TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '<REQUEST BODY>'
var client = new RestClient("https://rest.tsheets.com/api/v1/project_activity_read_times");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <TOKEN>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "<REQUEST BODY>", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/project_activity_read_times")
Dim request = New RestRequest(Method.POST)
request.AddHeader("Authorization", "Bearer <TOKEN>")
request.AddHeader("Content-Type", "application/json")
request.AddParameter("application/json", "<REQUEST BODY>", ParameterType.RequestBody);
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<REQUEST BODY>");
Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/project_activity_read_times")
  .post(body)
  .addHeader("Authorization", "Bearer <TOKEN>")
  .addHeader("Content-Type", "application/json")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/project_activity_read_times?ids=10001",
  "method": "POST",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
    "Content-Type", "application/json",
  },
  "processData": false,
  "data": "<REQUEST BODY>"
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'POST',
  url: 'https://rest.tsheets.com/api/v1/project_activity_read_times',
  headers: 
  { 
     'Authorization': 'Bearer <TOKEN>',
     'Content-Type': 'application/json',
  },
  body: '<REQUEST BODY>',
  json: true };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/project_activity_read_times');
$request->setMethod(HTTP_METH_POST);

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
  'Content-Type' => 'application/json',
));

$request->setBody('<REQUEST BODY>');

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/project_activity_read_times")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <TOKEN>',
request["Content-Type"] = 'application/json',
request.body = "<REQUEST BODY>"

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/project_activity_read_times"

payload = "<REQUEST BODY>"
headers = {
    'Authorization': 'Bearer <TOKEN>',
    'Content-Type': 'application/json',
    }

response = requests.request("POST", url, data=payload, headers=headers)

print(response.text)
package main

import (
  "fmt"
  "strings"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/project_activity_read_times"

  payload := strings.NewReader("<REQUEST BODY>")

  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, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))

}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
   "Content-Type": "application/json",
]
let parameters = <REQUEST BODY> as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/project_activity_read_times")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest,
  completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');
$client->addHeader('Content-Type', 'application/json');

$req = '<REQUEST BODY>';

$url="https://rest.tsheets.com/api/v1/project_activity_read_times"; 

$client->POST($url, $req);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "project_activity_read_times": {
      "1": {
        "_status_code": 200,
        "_status_message": "Created",
        "id": 10001,
        "user_id": 20001,
        "project_id": 30001,
        "latest_read_time": "2020-01-01T00:00:00+00:00"
      },
      "2": {
        "_status_code": 200,
        "_status_message": "Created",
        "id": 10002,
        "user_id": 20001,
        "project_id": 30002,
        "latest_read_time": "2020-01-05T00:00:00+00:00"
      },
    }
  },
  "supplemental_data": {
    "users": {
      "20001": {
        "id": 20001,
        "first_name": "Test",
        "last_name": "User",
        "active": true,
        "username": "test@user.com",
        "email": "test@user.com",
        "client_url": "your-company-url",
        "company_name": "Your Company"
      }
    },
    "projects": {
      "30001": {
        "id": 30001,
        "jobcode_id": 50001,
        "parent_jobcode_id": 0,
        "name": "Test Project",
        "status": "in_progress",
        "description": "Test Project for Docs",
        "start_date": "",
        "due_date": "",
        "completed_date": "",
        "active": true,
        "last_modified": "2019-11-21T18:42:06+00:00",
        "created": "2019-11-21T18:42:06+00:00",
        "linked_objects": {
            "notes_read_times": [
                159834
            ]
        }
      },
      {
        "id": 30002,
        "jobcode_id": 50002,
        "parent_jobcode_id": 1023134674,
        "name": "Test Project 2",
        "status": "in_progress",
        "description": "Test Project 2 for Docs",
        "start_date": "",
        "due_date": "",
        "completed_date": "",
        "active": true,
        "last_modified": "2019-11-21T18:42:06+00:00",
        "created": "2019-11-21T18:42:06+00:00",
        "linked_objects": {
            "notes_read_times": [
                160538
            ]
        }
      }
    }
  }
}

Update the last read time for one or more projects.

HTTP Request

posthttps://rest.tsheets.com/api/v1/project_activity_read_times

puthttps://rest.tsheets.com/api/v1/project_activity_read_times

Properties

Pass an array of project_activity_read_times objects as the value to a 'data' property (see example).

project_id
required
Int Id of Project object.

Status Codes

Each project_activity_read_time that is created will come back with a _status_code and _status_message that will indicate whether the project_activity_last_read was updated successfully. If there was a problem updating a project_activity_last_read, there may also be an additional field, _status_extra, which will contain more details about the failure.

201 Updated. Project Activity Read Time was updated successfully.
400 Bad Request. See the _status_extra value for more detail.

Project Activity Replies

The Project Activity Reply Object

Example

{
    "id": 10001,
    "project_activity_id": 40001,
    "user_id": 20001
    "note": "The client visited the site today.",
    "active": true,
    "created": "2019-05-09T18:46:44+00:00",
    "last_modified": "2019-06-25T16:06:03+00:00",
    "mentions": [],
    "linked_objects": {
        "project_activities": []
    }
}

Following is a list of the properties that belong to a project_activity_reply object, and a description of each.

id
read-only
Int ID of this project_note.
project_activity_id
read-only
Int ID of the associated project activity.
user_id
read-only
Int ID of the associated user.
note
read-only
String Content of note.
active
read-write
Boolean true or false. If false, this project activity reply is considered archived.
created
read-only
String Date/time when this project note was created, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm)
last_modified
read-only
String Date/time when this project note was last modified, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm).
linked_objects
read-write
Object A key/value map of all the objects linked to this project activity reply and the corresponding object ids.

Retrieve Project Activity Replies

Example: Retrieve a list of project activity replies given the required parameter project_activity_id.

Request

curl "https://rest.tsheets.com/api/v1/project_activity_replies?project_activity_id=40001" \
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/project_activity_replies?project_activity_id=40001");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/project_activity_replies?project_activity_id=40001")
Dim request = New RestRequest(Method.[GET])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/project_activity_replies?project_activity_id=40001")
  .get()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/project_activity_replies?project_activity_id=40001",
  "method": "GET",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'GET',
  url: 'https://rest.tsheets.com/api/v1/project_activity_replies',
  qs: {
    project_activity_id: '40001',
  },
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/project_activity_replies');
$request->setMethod(HTTP_METH_GET);

$request->setQueryData(array(
  'project_activity_id' => '40001',
));

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/project_activity_replies?project_activity_id=40001")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/project_activity_replies"

querystring = {
  "project_activity_id":"40001",
}

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/project_activity_replies?project_activity_id=40001"

  req, _ := http.NewRequest("GET", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/project_activity_replies?project_activity_id=40001")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest, completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/project_activity_replies?project_activity_id=40001"; 

$client->GET($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "project_activity_replies": {
      "10001": {
        "id": 10001,
        "project_activity_id": 30001,
        "user_id": 20001,
        "note": "note 1",
        "active": true,
        "created": "2019-12-12T22:34:04+00:00",
        "last_modified": "2019-12-12T22:34:04+00:00",
        "mentions": [],
        "linked_objects": {
          "project_activities": [
            40001
          ]
        }
      },
      "10002": {
        "id": 10002,
        "project_activity_id": 30001,
        "user_id": 20001,
        "note": "note 2",
        "active": true,
        "created": "2019-12-12T22:34:04+00:00",
        "last_modified": "2019-12-12T22:34:04+00:00",
        "mentions": [],
        "linked_objects": {
          "project_activities": [
            40001
          ]
        }
      },
      "10003": {
        "id": 10003,
        "project_activity_id": 30001,
        "user_id": 20001,
        "note": "note 3",
        "active": true,
        "created": "2019-12-09T20:18:04+00:00",
        "last_modified": "2019-12-09T20:18:04+00:00",
        "mentions": [],
        "linked_objects": {
          "project_activities": [
            40001
          ]
        }
      }
    }
  },
  "supplemental_data": {
    "users": {
      "20001": {
        "id": 20001,
        "first_name": "Test",
        "last_name": "User",
        "display_name": "",
        "group_id": 0,
        "active": true,
        "employee_number": 0,
        "salaried": false,
        "exempt": false,
        "username": "test@user.com",
        "email": "test@user.com",
        "email_verified": false,
        "payroll_id": "",
        "hire_date": "0000-00-00",
        "term_date": "0000-00-00",
        "last_modified": "2022-02-23T22:59:17+00:00",
        "last_active": "2022-05-09T21:36:43+00:00",
        "created": "2021-11-01T19:27:25+00:00",
        "client_url": "your-company-url",
        "company_name": "Your Company",
        "profile_image_url": "https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61",
        "pronouns": "",
        "mobile_number": "",
        "pto_balances": {
            "701818256": 0,
            "701818258": 0,
            "701818260": 0
        },
        "submitted_to": "2000-01-01",
        "approved_to": "2000-01-01",
        "manager_of_group_ids": [],
        "require_password_change": false,
        "pay_rate": 1,
        "pay_interval": "year",
        "permissions": {
            "admin": true,
            "mobile": true,
            "status_box": true,
            "reports": true,
            "manage_timesheets": true,
            "manage_authorization": true,
            "manage_users": true,
            "manage_my_timesheets": true,
            "manage_jobcodes": true,
            "pin_login": true,
            "approve_timesheets": true,
            "manage_schedules": false,
            "external_access": false,
            "manage_my_schedule": false,
            "manage_company_schedules": false,
            "view_company_schedules": false,
            "view_group_schedules": false,
            "manage_no_schedules": false,
            "view_my_schedules": false,
            "view_projects": false,
            "manage_projects": true,
            "time_tracking": true
        },
        "customfields": ""
      }
    },
    "project_activities": {
      "40001": {
        "id": 40001,
        "user_id": 20001,
        "project_id": 30001,
        "activity_type": "note",
        "active": true,
        "created": "2019-12-06T22:57:34+00:00",
        "last_modified": "2019-12-06T22:57:34+00:00",
        "unread_replies_count": 0,
        "following": true,
        "project_activity_metadata": [
        ],
        "linked_objects": {
          "project_activity_replies": [
            10001
          ]
        }
      }
    }
  },
  "more": false
}

Example: Retrieve a list of project activity replies having the given project_id parameter and given specific note ids.

Request

curl "https://rest.tsheets.com/api/v1/project_activity_replies?ids=10002&project_activity_id=40001" \
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/project_activity_replies?ids=10002&project_activity_id=40001");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/project_activity_replies?ids=10002&project_activity_id=40001")
Dim request = New RestRequest(Method.[GET])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/project_activity_replies?ids=10002&project_activity_id=40001")
  .get()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/project_activity_replies?ids=10002&project_activity_id=40001",
  "method": "GET",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'GET',
  url: 'https://rest.tsheets.com/api/v1/project_activity_replies',
  qs: {
    ids: '10002',
    project_activity_id: '40001',
  },
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/project_activity_replies');
$request->setMethod(HTTP_METH_GET);

$request->setQueryData(array(
  'ids' => '10002',
  'project_activity_id' => '40001',
));

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/project_activity_replies?ids=10002&project_activity_id=40001")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/project_activity_replies"

querystring = {
  "ids":"10002",
  "project_activity_id":"40001",
}

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/project_activity_replies?ids=10002&project_activity_id=40001"

  req, _ := http.NewRequest("GET", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/project_activity_replies?ids=10002&project_activity_id=40001")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest, completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/project_activity_replies?ids=10002&project_activity_id=40001"; 

$client->GET($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Retrieves a list of all project activity replies associated with a project, with optional filters to narrow down the results.

HTTP Request

gethttps://rest.tsheets.com/api/v1/project_activity_replies

Filter Parameters

project_activity_id
required
Int ID for one project_activity_id you’d like to filter on. Only replies with a project_activity_id set to this will be returned.
ids
optional
Int Comma separated list of one or more reply ids you would like to filter on. Only replies with an id set to one of these values will be returned. If omitted, all replies matching other specified filters are returned.
user_ids
optional
Int Comma separated list of one or more user ids you would like to filter on. Only replies with a user id set to one of these values will be returned. If omitted, all replies matching other specified filters are returned.
active
optional
String 'yes', 'no', or 'both'. Default is 'yes'. If a reply is active, it is available for selection during time entry.
modified_before
optional
String Only replies modified before this date/time will be returned, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm)
modified_since
optional
String Only replies modified since this date/time will be returned, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm)
supplemental_data
optional
String 'yes' or 'no'. Default is 'yes'. Indicates whether supplemental data should be returned.
per_page
optional
Int Deprecated. Use limit for new code.
Represents how many results you'd like to retrieve per request. Default is 50. Max is 50.
If a value over 50 is provided, it is ignored, and the max is used.
limit
optional
Int Represents how many results you'd like to retrieve per request. Default is 200. Max is 200.
If present, this value must be: an integer, greater than zero, and not greater than 200.
Setting limit less than 1 or greater than 200 will result in an error.
page
optional
Int Represents the page of results you would like to retrieve. Default is 1.

Create Project Activity Replies

Example: Project activity replies for a particular project activity.

Request Body

{
  "data": [
    {
      "note": "note 1",
      "project_activity_id": 40001
    },
    {
      "note": "note 2",
      "project_activity_id": 40001
    }
  ]
}


Request

curl -X POST \
  https://rest.tsheets.com/api/v1/project_activity_replies \
  -H 'Authorization: Bearer <TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '<REQUEST BODY>'
var client = new RestClient("https://rest.tsheets.com/api/v1/project_activity_replies");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <TOKEN>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "<REQUEST BODY>", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/project_activity_replies")
Dim request = New RestRequest(Method.POST)
request.AddHeader("Authorization", "Bearer <TOKEN>")
request.AddHeader("Content-Type", "application/json")
request.AddParameter("application/json", "<REQUEST BODY>", ParameterType.RequestBody);
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<REQUEST BODY>");
Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/project_activity_replies")
  .post(body)
  .addHeader("Authorization", "Bearer <TOKEN>")
  .addHeader("Content-Type", "application/json")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/project_activity_replies?ids=10002&project_activity_id=40001",
  "method": "POST",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
    "Content-Type", "application/json",
  },
  "processData": false,
  "data": "<REQUEST BODY>"
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'POST',
  url: 'https://rest.tsheets.com/api/v1/project_activity_replies',
  headers: 
  { 
     'Authorization': 'Bearer <TOKEN>',
     'Content-Type': 'application/json',
  },
  body: '<REQUEST BODY>',
  json: true };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/project_activity_replies');
$request->setMethod(HTTP_METH_POST);

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
  'Content-Type' => 'application/json',
));

$request->setBody('<REQUEST BODY>');

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/project_activity_replies")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <TOKEN>',
request["Content-Type"] = 'application/json',
request.body = "<REQUEST BODY>"

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/project_activity_replies"

payload = "<REQUEST BODY>"
headers = {
    'Authorization': 'Bearer <TOKEN>',
    'Content-Type': 'application/json',
    }

response = requests.request("POST", url, data=payload, headers=headers)

print(response.text)
package main

import (
  "fmt"
  "strings"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/project_activity_replies"

  payload := strings.NewReader("<REQUEST BODY>")

  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, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))

}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
   "Content-Type": "application/json",
]
let parameters = <REQUEST BODY> as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/project_activity_replies")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest,
  completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');
$client->addHeader('Content-Type', 'application/json');

$req = '<REQUEST BODY>';

$url="https://rest.tsheets.com/api/v1/project_activity_replies"; 

$client->POST($url, $req);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "project_activity_replies": {
      "1": {
        "_status_code": 200,
        "_status_message": "Created",
        "id": 10001,
        "project_activity_id": 40001,
        "user_id": 20001,
        "note": "note 1",
        "active": true,
        "created": "2019-12-12T22:34:04+00:00",
        "last_modified": "2019-12-12T22:34:04+00:00",
        "mentions": [],
        "linked_objects": {
          "project_activities": [
            40001
          ]
        }
      },
      "2": {
        "_status_code": 200,
        "_status_message": "Created",
        "id": 10002,
        "project_activity_id": 4001,
        "user_id": 20001,
        "note": "note 2",
        "active": true,
        "created": "2019-12-12T22:34:04+00:00",
        "last_modified": "2019-12-12T22:34:04+00:00",
        "mentions": [],
        "linked_objects": {
          "project_activities": [
            40002
          ]
        }
      },
    }
  },
  "supplemental_data": {
    "users": {
      "20001": {
        "id": 20001,
        "first_name": "Test",
        "last_name": "User",
        "display_name": "",
        "group_id": 0,
        "active": true,
        "employee_number": 0,
        "salaried": false,
        "exempt": false,
        "username": "test@user.com",
        "email": "test@user.com",
        "email_verified": false,
        "payroll_id": "",
        "hire_date": "0000-00-00",
        "term_date": "0000-00-00",
        "last_modified": "2022-02-23T22:59:17+00:00",
        "last_active": "2022-05-09T21:36:43+00:00",
        "created": "2021-11-01T19:27:25+00:00",
        "client_url": "your-company-url",
        "company_name": "Your Company",
        "profile_image_url": "https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61",
        "pronouns": "",
        "mobile_number": "",
        "pto_balances": {
            "701818256": 0,
            "701818258": 0,
            "701818260": 0
        },
        "submitted_to": "2000-01-01",
        "approved_to": "2000-01-01",
        "manager_of_group_ids": [],
        "require_password_change": false,
        "pay_rate": 1,
        "pay_interval": "year",
        "permissions": {
            "admin": true,
            "mobile": true,
            "status_box": true,
            "reports": true,
            "manage_timesheets": true,
            "manage_authorization": true,
            "manage_users": true,
            "manage_my_timesheets": true,
            "manage_jobcodes": true,
            "pin_login": true,
            "approve_timesheets": true,
            "manage_schedules": false,
            "external_access": false,
            "manage_my_schedule": false,
            "manage_company_schedules": false,
            "view_company_schedules": false,
            "view_group_schedules": false,
            "manage_no_schedules": false,
            "view_my_schedules": false,
            "view_projects": false,
            "manage_projects": true,
            "time_tracking": true
        },
        "customfields": ""
      }
    },
    "project_activities": {
      "40001": {
        "id": 40001,
        "user_id": 20001,
        "project_id": 30001,
        "activity_type": "note",
        "active": true,
        "created": "2019-12-06T22:57:34+00:00",
        "last_modified": "2019-12-06T22:57:34+00:00",
        "unread_replies_count": 0,
        "following": false,
        "project_activity_metadata": [
        ],
        "linked_objects": {
          "project_activity_replies": [
            10001
          ]
        }
      }
    }
  }
}

Create one or more replies to associate with a given project activity.

HTTP Request

posthttps://rest.tsheets.com/api/v1/project_activity_replies

Properties

Pass an array of project_activity_replies objects as the value to a 'data' property (see example).

note
required
String The note text itself
project_activity_id
required
Int Id of Project Activity object.

Status Codes

Each project_activity_reply that is created will come back with a _status_code and _status_message that will indicate whether the reply was created successfully. If there was a problem creating a reply, there may also be an additional field, _status_extra, which will contain more details about the failure.

201 Created. Project Activity Reply was created successfully.
400 Bad Request. See the _status_extra value for more detail.

Update Project Activity Replies

Example: Notes for a particular project.

Request Body

{
  "data": [
    {
      "id": 10001,
      "note": "note 1 - edited"
    },
    {
      "id": 20001,
      "note": "note 2 - deleted",
      "active": false
    }
  ]
}


Request

curl -X POST \
  https://rest.tsheets.com/api/v1/project_activity_replies \
  -H 'Authorization: Bearer <TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '<REQUEST BODY>'
var client = new RestClient("https://rest.tsheets.com/api/v1/project_activity_replies");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <TOKEN>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "<REQUEST BODY>", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/project_activity_replies")
Dim request = New RestRequest(Method.POST)
request.AddHeader("Authorization", "Bearer <TOKEN>")
request.AddHeader("Content-Type", "application/json")
request.AddParameter("application/json", "<REQUEST BODY>", ParameterType.RequestBody);
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<REQUEST BODY>");
Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/project_activity_replies")
  .post(body)
  .addHeader("Authorization", "Bearer <TOKEN>")
  .addHeader("Content-Type", "application/json")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/project_activity_replies?ids=10002&project_activity_id=40001",
  "method": "POST",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
    "Content-Type", "application/json",
  },
  "processData": false,
  "data": "<REQUEST BODY>"
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'POST',
  url: 'https://rest.tsheets.com/api/v1/project_activity_replies',
  headers: 
  { 
     'Authorization': 'Bearer <TOKEN>',
     'Content-Type': 'application/json',
  },
  body: '<REQUEST BODY>',
  json: true };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/project_activity_replies');
$request->setMethod(HTTP_METH_POST);

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
  'Content-Type' => 'application/json',
));

$request->setBody('<REQUEST BODY>');

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/project_activity_replies")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <TOKEN>',
request["Content-Type"] = 'application/json',
request.body = "<REQUEST BODY>"

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/project_activity_replies"

payload = "<REQUEST BODY>"
headers = {
    'Authorization': 'Bearer <TOKEN>',
    'Content-Type': 'application/json',
    }

response = requests.request("POST", url, data=payload, headers=headers)

print(response.text)
package main

import (
  "fmt"
  "strings"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/project_activity_replies"

  payload := strings.NewReader("<REQUEST BODY>")

  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, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))

}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
   "Content-Type": "application/json",
]
let parameters = <REQUEST BODY> as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/project_activity_replies")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest,
  completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');
$client->addHeader('Content-Type', 'application/json');

$req = '<REQUEST BODY>';

$url="https://rest.tsheets.com/api/v1/project_activity_replies"; 

$client->POST($url, $req);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "project_activity_replies": {
      "1": {
        "_status_code": 200,
        "_status_message": "Updated",
        "id": 10001,
        "project_activity_id": 40001,
        "user_id": 20001,
        "note": "note 1 - edited",
        "active": true,
        "created": "2019-12-12T22:34:04+00:00",
        "last_modified": "2019-12-12T22:34:04+00:00",
        "mentions": [],
        "linked_objects": {
          "project_activities": [
            40001
          ]
        }
      },
      "2": {
        "_status_code": 200,
        "_status_message": "Updated",
        "id": 10002,
        "project_activity_id": 40001,
        "user_id": 20001,
        "note": "note 2 - deleted",
        "active": false,
        "created": "2019-12-12T22:34:04+00:00",
        "last_modified": "2019-12-12T22:34:04+00:00",
        "mentions": [],
        "linked_objects": {
          "project_activities": [
            40002
          ]
        }
      },
    }
  },
  "supplemental_data": {
    "users": {
      "20001": {
        "id": 20001,
        "first_name": "Test",
        "last_name": "User",
        "display_name": "",
        "group_id": 0,
        "active": true,
        "employee_number": 0,
        "salaried": false,
        "exempt": false,
        "username": "test@user.com",
        "email": "test@user.com",
        "email_verified": false,
        "payroll_id": "",
        "hire_date": "0000-00-00",
        "term_date": "0000-00-00",
        "last_modified": "2022-02-23T22:59:17+00:00",
        "last_active": "2022-05-09T21:36:43+00:00",
        "created": "2021-11-01T19:27:25+00:00",
        "client_url": "your-company-url",
        "company_name": "Your Company",
        "profile_image_url": "https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61",
        "pronouns": "",
        "mobile_number": "",
        "pto_balances": {
            "701818256": 0,
            "701818258": 0,
            "701818260": 0
        },
        "submitted_to": "2000-01-01",
        "approved_to": "2000-01-01",
        "manager_of_group_ids": [],
        "require_password_change": false,
        "pay_rate": 1,
        "pay_interval": "year",
        "permissions": {
            "admin": true,
            "mobile": true,
            "status_box": true,
            "reports": true,
            "manage_timesheets": true,
            "manage_authorization": true,
            "manage_users": true,
            "manage_my_timesheets": true,
            "manage_jobcodes": true,
            "pin_login": true,
            "approve_timesheets": true,
            "manage_schedules": false,
            "external_access": false,
            "manage_my_schedule": false,
            "manage_company_schedules": false,
            "view_company_schedules": false,
            "view_group_schedules": false,
            "manage_no_schedules": false,
            "view_my_schedules": false,
            "view_projects": false,
            "manage_projects": true,
            "time_tracking": true
        },
        "customfields": ""
      }
    },
    "project_activities": {
      "40001": {
        "id": 40001,
        "user_id": 20001,
        "project_id": 30001,
        "activity_type": "note",
        "active": true,
        "created": "2019-12-06T22:57:34+00:00",
        "last_modified": "2019-12-06T22:57:34+00:00",
        "unread_replies_count": 0,
        "following": true,
        "project_activity_metadata": [
        ],
        "linked_objects": {
          "project_activity_replies": [
            10001
          ]
        }
      }
    }
  }
}

Update one or more replies to associate with a given project.

HTTP Request

puthttps://rest.tsheets.com/api/v1/project_activity_replies

Properties

Pass an array of project_activity_replies objects as the value to a 'data' property (see example).

id
required
Int Project Activity Reply ID of the reply you want to update.
note
optional
String The note text itself.
active
optional
Int 0 for inactive, 1 for active. Setting active to 0 will delete the reply from the feed.

Status Codes

Each project_activity_reply that is created will come back with a _status_code and _status_message that will indicate whether the reply was created successfully. If there was a problem creating a reply, there may also be an additional field, _status_extra, which will contain more details about the failure.

200 Created. Project Activity Reply was created successfully.
400 Bad Request. See the _status_extra value for more detail.

Project Notes

The Project Note Object

Example

{
    "id": 527093,
    "project_id": 6386831,
    "user_id": 234856
    "note": "The client visited the site today.",
    "active": true,
    "created": "2019-05-09T18:46:44+00:00",
    "last_modified": "2019-06-25T16:06:03+00:00",
    "mentions": [],
    "files": [1001, 1002, 1003],
    "linked_objects": {
        "project_activities": []
    }
}

Following is a list of the properties that belong to a project_note object, and a description of each.

id
read-only
Int ID of this project_note.
project_id
read-only
Int ID of the associated project.
user_id
read-only
Int ID of the associated user.
note
read-only
String Content of note.
active
read-write
Boolean true or false. If false, this project note is considered archived.
created
read-only
String Date/time when this project note was created, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm)
last_modified
read-only
String Date/time when this project note was last modified, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm).
files
read-only
Array List of ids for file attached to this note.
linked_objects
read-write
Object A key/value map of all the objects linked to this project note and the corresponding object ids.

Retrieve Project Notes

Example: Retrieve a list of project notes given the required parameter project_id.

Request

curl "https://rest.tsheets.com/api/v1/project_notes?project_id=1234" \
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/project_notes?project_id=1234");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/project_notes?project_id=1234")
Dim request = New RestRequest(Method.[GET])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/project_notes?project_id=1234")
  .get()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/project_notes?project_id=1234",
  "method": "GET",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'GET',
  url: 'https://rest.tsheets.com/api/v1/project_notes',
  qs: {
    project_id: '1234',
  },
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/project_notes');
$request->setMethod(HTTP_METH_GET);

$request->setQueryData(array(
  'project_id' => '1234',
));

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/project_notes?project_id=1234")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/project_notes"

querystring = {
  "project_id":"1234",
}

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/project_notes?project_id=1234"

  req, _ := http.NewRequest("GET", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/project_notes?project_id=1234")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest, completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/project_notes?project_id=1234"; 

$client->GET($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "project_notes": {
      "10001": {
        "id": 10001,
        "project_id": 30001,
        "user_id": 20001,
        "note": "note 1",
        "active": true,
        "created": "2019-12-12T22:34:04+00:00",
        "last_modified": "2019-12-12T22:34:04+00:00",
        "mentions": [],
        "files": [],
        "linked_objects": {
          "project_activities": [
            40001
          ]
        }
      },
      "10002": {
        "id": 10002,
        "project_id": 2992757,
        "user_id": 20001,
        "note": "note 3",
        "active": true,
        "created": "2019-12-12T22:34:04+00:00",
        "last_modified": "2019-12-12T22:34:04+00:00",
        "mentions": [],
        "files": [],
        "linked_objects": {
          "project_activities": [
            40002
          ]
        }
      },
      "10003": {
        "id": 10003,
        "project_id": 30001,
        "user_id": 20001,
        "note": "note 3",
        "active": true,
        "created": "2019-12-09T20:18:04+00:00",
        "last_modified": "2019-12-09T20:18:04+00:00",
        "mentions": [],
        "files": [],
        "linked_objects": {
          "project_activities": [
            40003
          ]
        }
      }
    }
  },
  "supplemental_data": {
    "users": {
      "20001": {
        "id": 20001,
        "first_name": "Test",
        "last_name": "User",
        "display_name": "",
        "group_id": 0,
        "active": true,
        "employee_number": 0,
        "salaried": false,
        "exempt": false,
        "username": "test@user.com",
        "email": "test@user.com",
        "email_verified": false,
        "payroll_id": "",
        "hire_date": "0000-00-00",
        "term_date": "0000-00-00",
        "last_modified": "2022-02-23T22:59:17+00:00",
        "last_active": "2022-05-09T21:36:43+00:00",
        "created": "2021-11-01T19:27:25+00:00",
        "client_url": "your-company-url",
        "company_name": "Your Company",
        "profile_image_url": "https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61",
        "pronouns": "",
        "mobile_number": "",
        "pto_balances": {
            "701818256": 0,
            "701818258": 0,
            "701818260": 0
        },
        "submitted_to": "2000-01-01",
        "approved_to": "2000-01-01",
        "manager_of_group_ids": [],
        "require_password_change": false,
        "pay_rate": 1,
        "pay_interval": "year",
        "permissions": {
            "admin": true,
            "mobile": true,
            "status_box": true,
            "reports": true,
            "manage_timesheets": true,
            "manage_authorization": true,
            "manage_users": true,
            "manage_my_timesheets": true,
            "manage_jobcodes": true,
            "pin_login": true,
            "approve_timesheets": true,
            "manage_schedules": false,
            "external_access": false,
            "manage_my_schedule": false,
            "manage_company_schedules": false,
            "view_company_schedules": false,
            "view_group_schedules": false,
            "manage_no_schedules": false,
            "view_my_schedules": false,
            "view_projects": false,
            "manage_projects": true,
            "time_tracking": true
        },
        "customfields": ""
      }
    },
    "projects": {
      "30001": {
        "id": 30001,
        "jobcode_id": 50001,
        "parent_jobcode_id": 0,
        "name": "Test Project",
        "status": "in_progress",
        "description": "Test Project for Docs",
        "start_date": "",
        "due_date": "",
        "completed_date": "",
        "active": true,
        "last_modified": "2019-11-21T18:42:06+00:00",
        "created": "2019-11-21T18:42:06+00:00",
        "linked_objects": {
            "notes_read_times": [
                159834
            ]
        }
      }
    },
    "project_activities": {
      "40001": {
        "id": 40001,
        "user_id": 20001,
        "project_id": 30001,
        "activity_type": "note",
        "active": true,
        "created": "2019-12-06T22:57:34+00:00",
        "last_modified": "2019-12-06T22:57:34+00:00",
        "unread_replies_count": 0,
        "following": false,
        "project_activity_metadata": [
        ],
        "linked_objects": {
          "project_notes": [
            10001
          ]
        }
      },
      "40002": {
        "id": 40002,
        "user_id": 20001,
        "project_id": 30001,
        "activity_type": "note",
        "active": true,
        "created": "2019-12-09T17:14:22+00:00",
        "last_modified": "2019-12-09T17:14:22+00:00",
        "unread_replies_count": 0,
        "following": false,
        "project_activity_metadata": [
        ],
        "linked_objects": {
          "project_notes": [
            10002
          ]
        }
      },
      "40003": {
        "id": 40003,
        "user_id": 20001,
        "project_id": 30001,
        "activity_type": "note",
        "active": true,
        "created": "2019-12-09T17:14:36+00:00",
        "last_modified": "2019-12-09T17:14:36+00:00",
        "project_activity_metadata": [
        ],
        "linked_objects": {
          "project_notes": [
            10003
          ]
        }
      }
    },
   "files": {
     "60001": {
       "id": 60001,
       "uploaded_by_user_id": 20001,
       "file_name": "test.png",
       "active": true,
       "size": 369302,
       "last_modified": "2018-10-05T03:57:49+00:00",
       "created": "2018-10-05T03:57:49+00:00",
       "linked_objects": {
           "projects": [30001],
           "project_notes": [10001]
       },
       "meta_data": {
          "image_rotation": "0"
       }
     },
     "60002": {
       "id": 60002,
       "uploaded_by_user_id": 20001,
       "file_name": "test_2.png",
       "active": true,
       "size": 369302,
       "last_modified": "2018-10-05T03:57:49+00:00",
       "created": "2018-10-05T03:57:49+00:00",
       "linked_objects": {
           "projects": [30001],
           "project_notes": [10001]
        },
       "meta_data": {
          "image_rotation": "0"
        }
      }
    }
  },
  "more": false
}

Example: Retrieve a list of project notes having the given project_id parameter and given specific note ids.

Request

curl "https://rest.tsheets.com/api/v1/project_notes?ids=12,367,3489&project_id=1234" \
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/project_notes?ids=12,367,3489&project_id=1234");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/project_notes?ids=12,367,3489&project_id=1234")
Dim request = New RestRequest(Method.[GET])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/project_notes?ids=12,367,3489&project_id=1234")
  .get()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/project_notes?ids=12,367,3489&project_id=1234",
  "method": "GET",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'GET',
  url: 'https://rest.tsheets.com/api/v1/project_notes',
  qs: {
    ids: '12,367,3489',
    project_id: '1234',
  },
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/project_notes');
$request->setMethod(HTTP_METH_GET);

$request->setQueryData(array(
  'ids' => '12,367,3489',
  'project_id' => '1234',
));

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/project_notes?ids=12,367,3489&project_id=1234")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/project_notes"

querystring = {
  "ids":"12,367,3489",
  "project_id":"1234",
}

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/project_notes?ids=12,367,3489&project_id=1234"

  req, _ := http.NewRequest("GET", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/project_notes?ids=12,367,3489&project_id=1234")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest, completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/project_notes?ids=12,367,3489&project_id=1234"; 

$client->GET($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Example: Retrieve a list of project notes having the given project_id parameter and given specific user ids.

Request

curl "https://rest.tsheets.com/api/v1/project_notes?user_ids=21,673,4893&project_id=1234" \
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/project_notes?user_ids=21,673,4893&project_id=1234");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/project_notes?user_ids=21,673,4893&project_id=1234")
Dim request = New RestRequest(Method.[GET])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/project_notes?user_ids=21,673,4893&project_id=1234")
  .get()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/project_notes?user_ids=21,673,4893&project_id=1234",
  "method": "GET",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'GET',
  url: 'https://rest.tsheets.com/api/v1/project_notes',
  qs: {
    user_ids: '21,673,4893',
    project_id: '1234',
  },
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/project_notes');
$request->setMethod(HTTP_METH_GET);

$request->setQueryData(array(
  'user_ids' => '21,673,4893',
  'project_id' => '1234',
));

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/project_notes?user_ids=21,673,4893&project_id=1234")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/project_notes"

querystring = {
  "user_ids":"21,673,4893",
  "project_id":"1234",
}

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/project_notes?user_ids=21,673,4893&project_id=1234"

  req, _ := http.NewRequest("GET", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/project_notes?user_ids=21,673,4893&project_id=1234")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest, completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/project_notes?user_ids=21,673,4893&project_id=1234"; 

$client->GET($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Retrieves a list of all project notes associated with a project, with optional filters to narrow down the results.

HTTP Request

gethttps://rest.tsheets.com/api/v1/project_notes

Filter Parameters

project_id
required
Int ID for one project you’d like to filter on. Only notes with a project_id set to this will be returned.
ids
optional
Int Comma separated list of one or more notes ids you would like to filter on. Only notes with an id set to one of these values will be returned. If omitted, all notes matching other specified filters are returned.
user_ids
optional
Int Comma separated list of one or more user ids you would like to filter on. Only notes with a user id set to one of these values will be returned. If omitted, all notes matching other specified filters are returned.
active
optional
String 'yes', 'no', or 'both'. Default is 'yes'. If a note is active, it is available for selection during time entry.
modified_before
optional
String Only notes modified before this date/time will be returned, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm)
modified_since
optional
String Only notes modified since this date/time will be returned, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm)
supplemental_data
optional
String 'yes' or 'no'. Default is 'yes'. Indicates whether supplemental data should be returned.
per_page
optional
Int Deprecated. Use limit for new code.
Represents how many results you'd like to retrieve per request. Default is 50. Max is 50.
If a value over 50 is provided, it is ignored, and the max is used.
limit
optional
Int Represents how many results you'd like to retrieve per request. Default is 200. Max is 200.
If present, this value must be: an integer, greater than zero, and not greater than 200.
Setting limit less than 1 or greater than 200 will result in an error.
page
optional
Int Represents the page of results you would like to retrieve. Default is 1.

Create Project Notes

Example: Notes for a particular project.

Request Body

{
  "data": [
    {
      "note": "note 1",
      "project_id": 30001,
      "files": [60001, 60002, 60003]
    },
    {
      "note": "note 2",
      "project_id": 30001,
      "files": [60011, 60012, 60013]
    }
  ]
}


Request

curl -X POST \
  https://rest.tsheets.com/api/v1/project_notes \
  -H 'Authorization: Bearer <TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '<REQUEST BODY>'
var client = new RestClient("https://rest.tsheets.com/api/v1/project_notes");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <TOKEN>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "<REQUEST BODY>", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/project_notes")
Dim request = New RestRequest(Method.POST)
request.AddHeader("Authorization", "Bearer <TOKEN>")
request.AddHeader("Content-Type", "application/json")
request.AddParameter("application/json", "<REQUEST BODY>", ParameterType.RequestBody);
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<REQUEST BODY>");
Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/project_notes")
  .post(body)
  .addHeader("Authorization", "Bearer <TOKEN>")
  .addHeader("Content-Type", "application/json")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/project_notes?user_ids=21,673,4893&project_id=1234",
  "method": "POST",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
    "Content-Type", "application/json",
  },
  "processData": false,
  "data": "<REQUEST BODY>"
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'POST',
  url: 'https://rest.tsheets.com/api/v1/project_notes',
  headers: 
  { 
     'Authorization': 'Bearer <TOKEN>',
     'Content-Type': 'application/json',
  },
  body: '<REQUEST BODY>',
  json: true };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/project_notes');
$request->setMethod(HTTP_METH_POST);

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
  'Content-Type' => 'application/json',
));

$request->setBody('<REQUEST BODY>');

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/project_notes")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <TOKEN>',
request["Content-Type"] = 'application/json',
request.body = "<REQUEST BODY>"

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/project_notes"

payload = "<REQUEST BODY>"
headers = {
    'Authorization': 'Bearer <TOKEN>',
    'Content-Type': 'application/json',
    }

response = requests.request("POST", url, data=payload, headers=headers)

print(response.text)
package main

import (
  "fmt"
  "strings"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/project_notes"

  payload := strings.NewReader("<REQUEST BODY>")

  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, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))

}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
   "Content-Type": "application/json",
]
let parameters = <REQUEST BODY> as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/project_notes")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest,
  completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');
$client->addHeader('Content-Type', 'application/json');

$req = '<REQUEST BODY>';

$url="https://rest.tsheets.com/api/v1/project_notes"; 

$client->POST($url, $req);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "project_notes": {
      "1": {
        "_status_code": 200,
        "_status_message": "Created",
        "id": 10001,
        "project_id": 30001,
        "user_id": 20001,
        "note": "note 1",
        "active": true,
        "created": "2019-12-12T22:34:04+00:00",
        "last_modified": "2019-12-12T22:34:04+00:00",
        "mentions": [],
        "files": [60001, 60002, 60003],
        "linked_objects": {
          "project_activities": [
            40001
          ]
        }
      },
      "2": {
        "_status_code": 200,
        "_status_message": "Created",
        "id": 10002,
        "project_id": 2992757,
        "user_id": 20001,
        "note": "note 2",
        "active": true,
        "created": "2019-12-12T22:34:04+00:00",
        "last_modified": "2019-12-12T22:34:04+00:00",
        "mentions": [],
        "files": [60011, 60012, 60013],
        "linked_objects": {
          "project_activities": [
            40002
          ]
        }
      },
    }
  },
  "supplemental_data": {
    "users": {
      "20001": {
        "id": 20001,
        "first_name": "Test",
        "last_name": "User",
        "display_name": "",
        "group_id": 0,
        "active": true,
        "employee_number": 0,
        "salaried": false,
        "exempt": false,
        "username": "test@user.com",
        "email": "test@user.com",
        "email_verified": false,
        "payroll_id": "",
        "hire_date": "0000-00-00",
        "term_date": "0000-00-00",
        "last_modified": "2022-02-23T22:59:17+00:00",
        "last_active": "2022-05-09T21:36:43+00:00",
        "created": "2021-11-01T19:27:25+00:00",
        "client_url": "your-company-url",
        "company_name": "Your Company",
        "profile_image_url": "https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61",
        "pronouns": "",
        "mobile_number": "",
        "pto_balances": {
            "701818256": 0,
            "701818258": 0,
            "701818260": 0
        },
        "submitted_to": "2000-01-01",
        "approved_to": "2000-01-01",
        "manager_of_group_ids": [],
        "require_password_change": false,
        "pay_rate": 1,
        "pay_interval": "year",
        "permissions": {
            "admin": true,
            "mobile": true,
            "status_box": true,
            "reports": true,
            "manage_timesheets": true,
            "manage_authorization": true,
            "manage_users": true,
            "manage_my_timesheets": true,
            "manage_jobcodes": true,
            "pin_login": true,
            "approve_timesheets": true,
            "manage_schedules": false,
            "external_access": false,
            "manage_my_schedule": false,
            "manage_company_schedules": false,
            "view_company_schedules": false,
            "view_group_schedules": false,
            "manage_no_schedules": false,
            "view_my_schedules": false,
            "view_projects": false,
            "manage_projects": true,
            "time_tracking": true
        },
        "customfields": ""
      }
    },
    "projects": {
      "30001": {
        "id": 30001,
        "jobcode_id": 50001,
        "parent_jobcode_id": 0,
        "name": "Test Project",
        "status": "in_progress",
        "description": "Test Project for Docs",
        "start_date": "",
        "due_date": "",
        "completed_date": "",
        "active": true,
        "last_modified": "2019-11-21T18:42:06+00:00",
        "created": "2019-11-21T18:42:06+00:00",
        "linked_objects": {
            "notes_read_times": [
                159834
            ]
        }
      }
    },
    "project_activities": {
      "40001": {
        "id": 40001,
        "user_id": 20001,
        "project_id": 30001,
        "activity_type": "note",
        "active": true,
        "created": "2019-12-06T22:57:34+00:00",
        "last_modified": "2019-12-06T22:57:34+00:00",
        "unread_replies_count": 0,
        "following": false,
        "project_activity_metadata": [
        ],
        "linked_objects": {
          "project_notes": [
            10001
          ]
        }
      },
      "40002": {
        "id": 40002,
        "user_id": 20001,
        "project_id": 30001,
        "activity_type": "note",
        "active": true,
        "created": "2019-12-09T17:14:22+00:00",
        "last_modified": "2019-12-09T17:14:22+00:00",
        "project_activity_metadata": [
        ],
        "linked_objects": {
          "project_notes": [
            10002
          ]
        }
      },
      "40003": {
        "id": 40003,
        "user_id": 20001,
        "project_id": 30001,
        "activity_type": "note",
        "active": true,
        "created": "2019-12-09T17:14:36+00:00",
        "last_modified": "2019-12-09T17:14:36+00:00",
        "project_activity_metadata": [
        ],
        "linked_objects": {
          "project_notes": [
            10003
          ]
        }
      }
    },
    "files": {
      "60001": {
        "id": 60001,
        "uploaded_by_user_id": 20001,
        "file_name": "test.png",
        "active": true,
        "size": 369302,
        "last_modified": "2018-10-05T03:57:49+00:00",
        "created": "2018-10-05T03:57:49+00:00",
        "linked_objects": {
            "projects": [30001],
            "project_notes": [10001]
        },
        "meta_data": {
           "image_rotation": "0"
        }
      },
      "60002": {
        "id": 60002,
        "uploaded_by_user_id": 20001,
        "file_name": "test_2.png",
        "active": true,
        "size": 66844,
        "last_modified": "2018-10-05T03:57:49+00:00",
        "created": "2018-10-05T03:57:49+00:00",
        "linked_objects": {
            "projects": [30001],
            "project_notes": [10001]
        },
        "meta_data": {
           "image_rotation": "0"
        }
      }
    }
  }
}

Create one or more notes to associate with a given project.

HTTP Request

posthttps://rest.tsheets.com/api/v1/project_notes

Properties

Pass an array of project_notes objects as the value to a 'data' property (see example).

note
required
String The note text itself
files
optional
Array List of file ids to be attached to this note.
project_id
required
Int Id of Project object.
user_id
optional
Int User ID to associate with this note

Status Codes

Each project_note that is created will come back with a _status_code and _status_message that will indicate whether the note was created successfully. If there was a problem creating a note, there may also be an additional field, _status_extra, which will contain more details about the failure.

201 Created. Project Note was created successfully.
400 Bad Request. See the _status_extra value for more detail.

Update Project Notes

Example: Notes for a particular project.

Request Body

{
  "data": [
    {
      "id": 10001,
      "note": "note 1 - edited",
      "files": [60001, 60020, 60021]
    },
    {
      "id": 20001,
      "note": "note 2 - deleted",
      "files": [],
      "active": false
    }
  ]
}


Request

curl -X POST \
  https://rest.tsheets.com/api/v1/project_notes \
  -H 'Authorization: Bearer <TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '<REQUEST BODY>'
var client = new RestClient("https://rest.tsheets.com/api/v1/project_notes");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <TOKEN>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "<REQUEST BODY>", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/project_notes")
Dim request = New RestRequest(Method.POST)
request.AddHeader("Authorization", "Bearer <TOKEN>")
request.AddHeader("Content-Type", "application/json")
request.AddParameter("application/json", "<REQUEST BODY>", ParameterType.RequestBody);
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<REQUEST BODY>");
Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/project_notes")
  .post(body)
  .addHeader("Authorization", "Bearer <TOKEN>")
  .addHeader("Content-Type", "application/json")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/project_notes?user_ids=21,673,4893&project_id=1234",
  "method": "POST",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
    "Content-Type", "application/json",
  },
  "processData": false,
  "data": "<REQUEST BODY>"
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'POST',
  url: 'https://rest.tsheets.com/api/v1/project_notes',
  headers: 
  { 
     'Authorization': 'Bearer <TOKEN>',
     'Content-Type': 'application/json',
  },
  body: '<REQUEST BODY>',
  json: true };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/project_notes');
$request->setMethod(HTTP_METH_POST);

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
  'Content-Type' => 'application/json',
));

$request->setBody('<REQUEST BODY>');

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/project_notes")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <TOKEN>',
request["Content-Type"] = 'application/json',
request.body = "<REQUEST BODY>"

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/project_notes"

payload = "<REQUEST BODY>"
headers = {
    'Authorization': 'Bearer <TOKEN>',
    'Content-Type': 'application/json',
    }

response = requests.request("POST", url, data=payload, headers=headers)

print(response.text)
package main

import (
  "fmt"
  "strings"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/project_notes"

  payload := strings.NewReader("<REQUEST BODY>")

  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, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))

}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
   "Content-Type": "application/json",
]
let parameters = <REQUEST BODY> as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/project_notes")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest,
  completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');
$client->addHeader('Content-Type', 'application/json');

$req = '<REQUEST BODY>';

$url="https://rest.tsheets.com/api/v1/project_notes"; 

$client->POST($url, $req);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "project_notes": {
      "1": {
        "_status_code": 200,
        "_status_message": "Updated",
        "id": 10001,
        "project_id": 30001,
        "user_id": 20001,
        "note": "note 1 - edited",
        "active": true,
        "created": "2019-12-12T22:34:04+00:00",
        "last_modified": "2019-12-12T22:34:04+00:00",
        "mentions": [],
        "files": [60001, 60020, 60021],
        "linked_objects": {
          "project_activities": [
            40001
          ]
        }
      },
      "2": {
        "_status_code": 200,
        "_status_message": "Updated",
        "id": 10002,
        "project_id": 2992757,
        "user_id": 20001,
        "note": "note 2 - deleted",
        "active": false,
        "created": "2019-12-12T22:34:04+00:00",
        "last_modified": "2019-12-12T22:34:04+00:00",
        "mentions": [],
        "files": [],
        "linked_objects": {
          "project_activities": [
            40002
          ]
        }
      },
    }
  },
  "supplemental_data": {
    "users": {
      "20001": {
        "id": 20001,
        "first_name": "Test",
        "last_name": "User",
        "display_name": "",
        "group_id": 0,
        "active": true,
        "employee_number": 0,
        "salaried": false,
        "exempt": false,
        "username": "test@user.com",
        "email": "test@user.com",
        "email_verified": false,
        "payroll_id": "",
        "hire_date": "0000-00-00",
        "term_date": "0000-00-00",
        "last_modified": "2022-02-23T22:59:17+00:00",
        "last_active": "2022-05-09T21:36:43+00:00",
        "created": "2021-11-01T19:27:25+00:00",
        "client_url": "your-company-url",
        "company_name": "Your Company",
        "profile_image_url": "https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61",
        "pronouns": "",
        "mobile_number": "",
        "pto_balances": {
            "701818256": 0,
            "701818258": 0,
            "701818260": 0
        },
        "submitted_to": "2000-01-01",
        "approved_to": "2000-01-01",
        "manager_of_group_ids": [],
        "require_password_change": false,
        "pay_rate": 1,
        "pay_interval": "year",
        "permissions": {
            "admin": true,
            "mobile": true,
            "status_box": true,
            "reports": true,
            "manage_timesheets": true,
            "manage_authorization": true,
            "manage_users": true,
            "manage_my_timesheets": true,
            "manage_jobcodes": true,
            "pin_login": true,
            "approve_timesheets": true,
            "manage_schedules": false,
            "external_access": false,
            "manage_my_schedule": false,
            "manage_company_schedules": false,
            "view_company_schedules": false,
            "view_group_schedules": false,
            "manage_no_schedules": false,
            "view_my_schedules": false,
            "view_projects": false,
            "manage_projects": true,
            "time_tracking": true
        },
        "customfields": ""
      }
    },
    "projects": {
      "30001": {
        "id": 30001,
        "jobcode_id": 50001,
        "parent_jobcode_id": 0,
        "name": "Test Project",
        "status": "in_progress",
        "description": "Test Project for Docs",
        "start_date": "",
        "due_date": "",
        "completed_date": "",
        "active": true,
        "last_modified": "2019-11-21T18:42:06+00:00",
        "created": "2019-11-21T18:42:06+00:00",
        "linked_objects": {
            "notes_read_times": [
                159834
            ]
        }
      }
    },
    "project_activities": {
      "40001": {
        "id": 40001,
        "user_id": 20001,
        "project_id": 30001,
        "activity_type": "note",
        "active": true,
        "created": "2019-12-06T22:57:34+00:00",
        "last_modified": "2019-12-06T22:57:34+00:00",
        "unread_replies_count": 0,
        "following": false,
        "project_activity_metadata": [
        ],
        "linked_objects": {
          "project_notes": [
            10001
          ]
        }
      },
      "40002": {
        "id": 40002,
        "user_id": 20001,
        "project_id": 30001,
        "activity_type": "note",
        "active": true,
        "created": "2019-12-09T17:14:22+00:00",
        "last_modified": "2019-12-09T17:14:22+00:00",
        "unread_replies_count": 0,
        "following": false,
        "project_activity_metadata": [
        ],
        "linked_objects": {
          "project_notes": [
            10002
          ]
        }
      },
      "40003": {
        "id": 40003,
        "user_id": 20001,
        "project_id": 30001,
        "activity_type": "note",
        "active": true,
        "created": "2019-12-09T17:14:36+00:00",
        "last_modified": "2019-12-09T17:14:36+00:00",
        "unread_replies_count": 0,
        "following": false,
        "project_activity_metadata": [
        ],
        "linked_objects": {
          "project_notes": [
            10003
          ]
        }
      }
    },
    "files": {
      "60001": {
        "id": 60001,
        "uploaded_by_user_id": 20001,
        "file_name": "test.png",
        "active": true,
        "size": 369302,
        "last_modified": "2018-10-05T03:57:49+00:00",
        "created": "2018-10-05T03:57:49+00:00",
        "linked_objects": {
            "projects": [30001],
            "project_notes": [10001]
        },
        "meta_data": {
           "image_rotation": "0"
        }
      },
      "60020": {
        "id": 60020,
        "uploaded_by_user_id": 20001,
        "file_name": "test_20.png",
        "active": true,
        "size": 66844,
        "last_modified": "2018-10-05T03:57:49+00:00",
        "created": "2018-10-05T03:57:49+00:00",
        "linked_objects": {
            "projects": [30001],
            "project_notes": [10001]
        },
        "meta_data": {
           "image_rotation": "0"
        }
      }
    }
  }
}

Update one or more notes to associate with a given project.

HTTP Request

puthttps://rest.tsheets.com/api/v1/project_notes

Properties

Pass an array of project_notes objects as the value to a 'data' property (see example).

id
required
Int Note ID of the note you want to update.
note
optional
String The note text itself.
files
optional
Array List of file ids to be attached to this note. Submit empty array to remove any attached files.
active
optional
Int 0 for inactive, 1 for active. This deletes the note from the feed.

Status Codes

Each project_note that is created will come back with a _status_code and _status_message that will indicate whether the note was created successfully. If there was a problem creating a note, there may also be an additional field, _status_extra, which will contain more details about the failure.

200 Created. Project Note was created successfully.
400 Bad Request. See the _status_extra value for more detail.

Reminders

The Reminder Object

Example

{
  "id": 72595,
  "reminder_type": "clock-in",
  "due_time": "23:00:00",
  "due_days_of_week": "Mon,Tue,Thu,Fri",
  "distribution_methods": "Push,SMS",
  "active": true,
  "enabled": true,
  "last_modified": "2018-07-15T19:33:57+00:00",
  "created": "2018-07-15T19:08:33+00:00",
  "user_id": 0
}

Following is a list of the properties that belong to a reminder object, and a description of each.

id
read-only
Int Id of reminder.
user_id
read-only
Int Id of the user that this reminder pertains to. A user_id of 0 indicates that this is a company-wide reminder.
reminder_type
read-write
String The type of this reminder object. Supported reminder_types are 'clock-in' and 'clock-out'.
due_time
read-write
String The 24-hour time that the reminder should be sent, expressed as 'hh:mm:ss'. The time should be in the recipient user's local time and must be in even 5 minute increments. For example: '13:45:00' or '08:00:00'.
due_days_of_week
read-write
String A comma-separated list of the days of the week when the reminder should be sent. The value can be any combination of 'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri' and 'Sat'. For example: 'Mon,Tue,Wed,Thu,Fri' or 'Tue,Sat'.
distribution_methods
read-write
String A comma-separated list of the transport method(s) indicating how the reminder message should be sent. The value can be any combination of 'Push', 'SMS' and 'Email'. For example: 'Push,SMS'. The 'Push' method utilizes the TSheets mobile app to deliver the notification to a mobile device.
active
read-write
Boolean If true, this reminder is active and will be evaluated at the 'due_time' and 'due_days_of_week'. If false, this reminder is inactive and will not be evaluated. If active=false for user-specific reminders, then the company-wide reminder of the same reminder type will apply.
enabled
read-write
Boolean If true, the reminder is enabled and will be sent at the 'due_time' and 'due_days_of_week'. If false, the reminder is disabled and will not be sent. A user with an active (active = true), but disabled (enabled = false) reminder will not receive that reminder type regardless of how company-wide reminders are configured.
last_modified
read-only
String Date/time when this reminder was last modified, in ISO 8601 format ('YYYY-MM-DDThh:mm:ss±hh:mm')
created
read-only
String Date/time when this reminder was created, in ISO 8601 format ('YYYY-MM-DDThh:mm:ss±hh:mm')

Retrieve Reminders

Example: Retrieve company-wide and user-specific clock-in and clock-out reminders for a user.

Request

curl "https://rest.tsheets.com/api/v1/reminders?user_ids=0,37&reminder_types=clock-in,clock-out" \
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/reminders?user_ids=0,37&reminder_types=clock-in,clock-out");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/reminders?user_ids=0,37&reminder_types=clock-in,clock-out")
Dim request = New RestRequest(Method.[GET])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/reminders?user_ids=0,37&reminder_types=clock-in,clock-out")
  .get()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/reminders?user_ids=0,37&reminder_types=clock-in,clock-out",
  "method": "GET",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'GET',
  url: 'https://rest.tsheets.com/api/v1/reminders',
  qs: {
    user_ids: '0,37',
    reminder_types: 'clock-in,clock-out',
  },
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/reminders');
$request->setMethod(HTTP_METH_GET);

$request->setQueryData(array(
  'user_ids' => '0,37',
  'reminder_types' => 'clock-in,clock-out',
));

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/reminders?user_ids=0,37&reminder_types=clock-in,clock-out")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/reminders"

querystring = {
  "user_ids":"0,37",
  "reminder_types":"clock-in,clock-out",
}

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/reminders?user_ids=0,37&reminder_types=clock-in,clock-out"

  req, _ := http.NewRequest("GET", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/reminders?user_ids=0,37&reminder_types=clock-in,clock-out")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest, completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/reminders?user_ids=0,37&reminder_types=clock-in,clock-out"; 

$client->GET($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "reminders": {
      "72595": {
        "id": 72595,
        "reminder_type": "clock-in",
        "due_time": "23:00:00",
        "due_days_of_week": "Mon,Tue,Thu,Fri",
        "distribution_methods": "Push,SMS",
        "active": true,
        "enabled": true,
        "last_modified": "2018-07-15T19:33:57+00:00",
        "created": "2018-07-15T19:08:33+00:00",
        "user_id": 0
      },
      "72597": {
        "id": 72597,
        "reminder_type": "clock-out",
        "due_time": "04:00:00",
        "due_days_of_week": "Mon,Tue,Thu,Fri",
        "distribution_methods": "Push,SMS",
        "active": true,
        "enabled": false,
        "last_modified": "2018-07-15T19:33:57+00:00",
        "created": "2018-07-15T19:08:33+00:00",
        "user_id": 0
      },
      "72599": {
        "id": 72599,
        "reminder_type": "clock-in",
        "due_time": "13:40:00",
        "due_days_of_week": "Mon,Tue,Wed,Thu,Fri",
        "distribution_methods": "Push,SMS",
        "active": true,
        "enabled": true,
        "last_modified": "2018-07-15T19:31:43+00:00",
        "created": "2018-07-15T19:16:19+00:00",
        "user_id": 37
      },
      "72601": {
        "id": 72601,
        "reminder_type": "clock-out",
        "due_time": "17:00:00",
        "due_days_of_week": "Mon,Tue,Wed,Thu,Fri",
        "distribution_methods": "Push,SMS",
        "active": true,
        "enabled": true,
        "last_modified": "2018-07-15T19:31:43+00:00",
        "created": "2018-07-15T19:16:19+00:00",
        "user_id": 37
      }
    }
  }
}

Example: Retrieve user-specific clock-in and clock-out reminders that have been modified since a specific date and time.

Request

curl "https://rest.tsheets.com/api/v1/reminders?user_ids=0,37&reminder_types=clock-in&modified_since=2018-07-15T19:32:00-06:00" \
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/reminders?user_ids=0,37&reminder_types=clock-in&modified_since=2018-07-15T19:32:00-06:00");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/reminders?user_ids=0,37&reminder_types=clock-in&modified_since=2018-07-15T19:32:00-06:00")
Dim request = New RestRequest(Method.[GET])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/reminders?user_ids=0,37&reminder_types=clock-in&modified_since=2018-07-15T19:32:00-06:00")
  .get()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/reminders?user_ids=0,37&reminder_types=clock-in&modified_since=2018-07-15T19:32:00-06:00",
  "method": "GET",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'GET',
  url: 'https://rest.tsheets.com/api/v1/reminders',
  qs: {
    user_ids: '0,37',
    reminder_types: 'clock-in',
    modified_since: '2018-07-15T19:32:00-06:00',
  },
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/reminders');
$request->setMethod(HTTP_METH_GET);

$request->setQueryData(array(
  'user_ids' => '0,37',
  'reminder_types' => 'clock-in',
  'modified_since' => '2018-07-15T19:32:00-06:00',
));

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/reminders?user_ids=0,37&reminder_types=clock-in&modified_since=2018-07-15T19:32:00-06:00")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/reminders"

querystring = {
  "user_ids":"0,37",
  "reminder_types":"clock-in",
  "modified_since":"2018-07-15T19:32:00-06:00",
}

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/reminders?user_ids=0,37&reminder_types=clock-in&modified_since=2018-07-15T19:32:00-06:00"

  req, _ := http.NewRequest("GET", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/reminders?user_ids=0,37&reminder_types=clock-in&modified_since=2018-07-15T19:32:00-06:00")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest, completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/reminders?user_ids=0,37&reminder_types=clock-in&modified_since=2018-07-15T19:32:00-06:00"; 

$client->GET($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "reminders": {
      "72595": {
        "id": 72595,
        "reminder_type": "clock-in",
        "due_time": "23:00:00",
        "due_days_of_week": "Mon,Tue,Thu,Fri",
        "distribution_methods": "Push,SMS",
        "active": true,
        "enabled": true,
        "last_modified": "2018-07-15T19:33:57+00:00",
        "created": "2018-07-15T19:08:33+00:00",
        "user_id": 0
      }
    }
  }
}

Retrieves a list of reminders associated with your employees or company, with filters to narrow down the results.

HTTP Request

gethttps://rest.tsheets.com/api/v1/reminders

Filter Parameters

user_ids
required
Int Comma-separated list of one or more user ids to retrieve reminders for. Include a user_id of 0 to retrieve company-wide reminders.
reminder_types
optional
String Comma-separated list of one or more reminder types to retrieve reminders for. Current legal values are 'clock-in' and 'clock-out'. For example, specify 'clock-in,clock-out' to retrieve both clock-in and clock-out reminders.
modified_since
optional
String Only reminders modified since this date/time will be returned, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm)
supplemental_data
optional
String 'yes' or 'no'. Default is 'yes'. Indicates whether supplemental data should be returned.

Create Reminders

Example: Create user-specific clock-in and clock-out reminders for a user.

Request Body

{
  "data": [{
    "user_id": 37,
    "reminder_type": "clock-in",
    "due_time": "08:10:00",
    "due_days_of_week": "Mon,Tue,Sat,Sun",
    "distribution_methods": "Push,SMS,Email",
    "active": true,
    "enabled": true
  }, {
    "user_id": 37,
    "reminder_type": "clock-out",
    "due_time": "18:20:00",
    "due_days_of_week": "Mon,Tue,Sat,Sun",
    "distribution_methods": "Push,SMS,Email",
    "active": true,
    "enabled": false
  }]
}

Request

curl -X POST \
  https://rest.tsheets.com/api/v1/reminders \
  -H 'Authorization: Bearer <TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '<REQUEST BODY>'
var client = new RestClient("https://rest.tsheets.com/api/v1/reminders");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <TOKEN>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "<REQUEST BODY>", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/reminders")
Dim request = New RestRequest(Method.POST)
request.AddHeader("Authorization", "Bearer <TOKEN>")
request.AddHeader("Content-Type", "application/json")
request.AddParameter("application/json", "<REQUEST BODY>", ParameterType.RequestBody);
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<REQUEST BODY>");
Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/reminders")
  .post(body)
  .addHeader("Authorization", "Bearer <TOKEN>")
  .addHeader("Content-Type", "application/json")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/reminders?user_ids=0,37&reminder_types=clock-in&modified_since=2018-07-15T19:32:00-06:00",
  "method": "POST",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
    "Content-Type", "application/json",
  },
  "processData": false,
  "data": "<REQUEST BODY>"
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'POST',
  url: 'https://rest.tsheets.com/api/v1/reminders',
  headers: 
  { 
     'Authorization': 'Bearer <TOKEN>',
     'Content-Type': 'application/json',
  },
  body: '<REQUEST BODY>',
  json: true };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/reminders');
$request->setMethod(HTTP_METH_POST);

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
  'Content-Type' => 'application/json',
));

$request->setBody('<REQUEST BODY>');

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/reminders")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <TOKEN>',
request["Content-Type"] = 'application/json',
request.body = "<REQUEST BODY>"

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/reminders"

payload = "<REQUEST BODY>"
headers = {
    'Authorization': 'Bearer <TOKEN>',
    'Content-Type': 'application/json',
    }

response = requests.request("POST", url, data=payload, headers=headers)

print(response.text)
package main

import (
  "fmt"
  "strings"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/reminders"

  payload := strings.NewReader("<REQUEST BODY>")

  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, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))

}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
   "Content-Type": "application/json",
]
let parameters = <REQUEST BODY> as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/reminders")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest,
  completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');
$client->addHeader('Content-Type', 'application/json');

$req = '<REQUEST BODY>';

$url="https://rest.tsheets.com/api/v1/reminders"; 

$client->POST($url, $req);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "reminders": {
      "1": {
        "_status_code": 200,
        "_status_message": "Created",
        "user_id": 37,
        "reminder_type": "clock-in",
        "due_time": "08:10:00",
        "due_days_of_week": "Mon,Tue,Sat,Sun",
        "distribution_methods": "Push,SMS,Email",
        "active": true,
        "enabled": true,
        "id": "73033"
      },
      "2": {
        "_status_code": 200,
        "_status_message": "Created",
        "user_id": 37,
        "reminder_type": "clock-out",
        "due_time": "18:20:00",
        "due_days_of_week": "Mon,Tue,Sat,Sun",
        "distribution_methods": "Push,SMS,Email",
        "active": true,
        "enabled": false,
        "id": "73035"
      }
    }
  }
}

Add one or more user-specific or company-wide reminders.

HTTP Request

posthttps://rest.tsheets.com/api/v1/reminders

Properties

Pass an array of reminder objects as the value to a 'data' property (see example).

user_id
required
Int Id of the user that this reminder pertains to. A user_id of 0 indicates that this is a company-wide reminder.
reminder_type
required
String The type of this reminder object. Supported reminder_types are 'clock-in' and 'clock-out'.
due_time
required
String The 24-hour time that the reminder should be sent, expressed as "hh:mm:ss". The time should be in the user's local time and must be in even 5 minute increments. For example: '13:45:00' or '08:00:00'.
due_days_of_week
required
String A comma-separated list of the days of the week when the reminder should be sent. The value can be any combination of 'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri' and 'Sat'. For example: 'Mon,Tue,Wed,Thu,Fri' or 'Tue,Sat'.
distribution_methods
required
String A comma-separated list of the transport method(s) indicating how the reminder message should be sent. The value can be any combination of 'Push', 'SMS' and 'Email'. For example: "Push,SMS". The 'Push' method utilizes the TSheets mobile app to deliver the notification to a mobile device. The 'SMS' method requires that the 'Text Messaging' Add-On be installed and that a 'Cell Number' is registered for each employee.
active
required
Boolean true or false. If true, this reminder is active and will be evaluated at the 'due_time' and 'due_days_of_week'. If false, this reminder is inactive and will not be evaluated. If active = false for user-specific reminders, then the company-wide reminder (of the same reminder type) will apply.
enabled
required
Boolean true or false. If true, the reminder is enabled and will be sent at the 'due_time' and 'due_days_of_week'. If false, the reminder is disabled and will not be sent. A user with an active (active = true) but disabled (enabled = false) reminder will not receive that reminder type regardless of how company-wide reminders are configured.

For a full list of the properties that may be set on a reminder, see the Reminder object.

Status Codes

Each reminder that is created will come back with a _status_code and _status_message that will indicate whether the reminder was created successfully. If there was a problem creating a reminder, there may also be an additional field, _status_extra, which will contain more details about the failure.

200 OK. Reminder was created successfully.
202 OK. Reminder accepted but not created because this reminder_type exists for the specified user.
406 Failed. Duplicate entry.
417 Expectation Failed. Something was wrong or missing with the properties supplied for this reminder. See the _status_extra value for more detail.

Update Reminders

Example: Edit a user's clock-in and clock-out reminder due times and days of week.

Request Body

{
  "data": [{
    "user_id": 37,
    "reminder_type": "clock-in",
    "due_time": "08:10:00",
    "due_days_of_week": "Mon,Tue,Sat,Sun",
    "distribution_methods": "Push,SMS,Email",
    "active": true,
    "enabled": true
  }, {
    "user_id": 37,
    "reminder_type": "clock-out",
    "due_time": "18:20:00",
    "due_days_of_week": "Mon,Tue,Sat,Sun",
    "distribution_methods": "Push,SMS,Email",
    "active": true,
    "enabled": false
  }]
}

Request

curl -X PUT \
  https://rest.tsheets.com/api/v1/reminders \
  -H 'Authorization: Bearer <TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '<REQUEST BODY>'
var client = new RestClient("https://rest.tsheets.com/api/v1/reminders");
var request = new RestRequest(Method.PUT);
request.AddHeader("Authorization", "Bearer <TOKEN>");
request.AddHeader("Content-Type", "application/json");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/reminders")
Dim request = New RestRequest(Method.PUT)
request.AddHeader("Authorization", "Bearer <TOKEN>")
request.AddHeader("Content-Type", "application/json")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<REQUEST BODY>");
Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/reminders")
  .put(body)
  .addHeader("Authorization", "Bearer <TOKEN>")
  .addHeader("Content-Type", "application/json")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/reminders?user_ids=0,37&reminder_types=clock-in&modified_since=2018-07-15T19:32:00-06:00",
  "method": "PUT",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
    "Content-Type", "application/json",
  },
  "processData": false,
  "data": "<REQUEST BODY>"
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'PUT',
  url: 'https://rest.tsheets.com/api/v1/reminders',
  headers: 
  { 
     'Authorization': 'Bearer <TOKEN>',
     'Content-Type': 'application/json',
  },
  body: '<REQUEST BODY>',
  json: true };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/reminders');
$request->setMethod(HTTP_METH_PUT);

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
  'Content-Type' => 'application/json',
));

$request->setBody('<REQUEST BODY>');

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/reminders")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <TOKEN>',
request["Content-Type"] = 'application/json',
request.body = "<REQUEST BODY>"

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/reminders"

payload = "<REQUEST BODY>"
headers = {
    'Authorization': 'Bearer <TOKEN>',
    'Content-Type': 'application/json',
    }

response = requests.request("PUT", url, data=payload, headers=headers)

print(response.text)
package main

import (
  "fmt"
  "strings"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/reminders"

  payload := strings.NewReader("<REQUEST BODY>")

  req, _ := http.NewRequest("PUT", 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, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))

}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
   "Content-Type": "application/json",
]
let parameters = <REQUEST BODY> as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(
  url: NSURL(string: "http://rest.tsheets.com/api/v1/reminders")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "PUT"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest,
  completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');
$client->addHeader('Content-Type', 'application/json');

$req = '<REQUEST BODY>';

$url="http://rest.tsheets.com/api/v1/reminders"; 

$client->PUT($url, $req);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "reminders": {
      "1": {
        "_status_code": 200,
        "_status_message": "Created",
        "user_id": 37,
        "reminder_type": "clock-in",
        "due_time": "08:10:00",
        "due_days_of_week": "Mon,Tue,Sat,Sun",
        "distribution_methods": "Push,SMS,Email",
        "active": true,
        "enabled": true,
        "id": "73033"
      },
      "2": {
        "_status_code": 200,
        "_status_message": "Created",
        "user_id": 37,
        "reminder_type": "clock-out",
        "due_time": "18:20:00",
        "due_days_of_week": "Mon,Tue,Sat,Sun",
        "distribution_methods": "Push,SMS,Email",
        "active": true,
        "enabled": false,
        "id": "73035"
      }
    }
  }
}

Edit one or more reminders for employees within your company.

HTTP Request

puthttps://rest.tsheets.com/api/v1/reminders

Properties

Pass an array of reminder objects as the value to a 'data' property (see example).

id
required
Int Id of the reminder.

Other properties defined on a reminder object may be passed in to the request with a new value in order to change it. If the value passed in is the same as it was previously, or if a particular property is not passed in at all, it will not be updated.

Status Codes

Each reminder that is edited will come back with a _status_code and _status_message that will indicate whether the reminder was edited successfully. If there was a problem editing a reminder, there may also be an additional field, _status_extra, which will contain more details about the failure.

200 OK. Reminder was edited successfully.
406 Failed. Duplicate entry.
417 Expectation Failed. Something was wrong or missing with the properties supplied for this reminder. See the _status_extra value for more detail.

Reports

Retrieve Current Totals Report

Response Layout

{
  "results": {
    "current_totals": {
      "1751136": {                             # Totals are indexed by unique 
        "user_id": 1751136,                    #   user_id.
        "on_the_clock": true,                  # Whether this user is currently
                                               #   on the clock.
        "timesheet_id": 173523290,             # Timesheet id for the current 
                                               #   timesheet.
        "jobcode_id": 26730062,                # Jobcode id for the current 
                                               #   timesheet.
        "group_id": 180010,                    # Unique group id for this user,
                                               #   value of zero represents those
                                               #   without a group.
        "shift_geolocations_available": true,  # If geolocations are available 
                                               #   for the current timesheet.
        "shift_seconds": 25275,                # Total time for the current
                                               #   shift, in seconds.
        "day_seconds": 25275                   # Total time for the day, 
                                               #   in seconds.
      },
      "1738864": {
        "user_id": 1738864,
        "on_the_clock": false,
        "timesheet_id": null,
        "jobcode_id": null,
        "group_id": 180010,
        "shift_geolocations_available": false,
        "shift_seconds": 0,
        "day_seconds": 25719
      },
      ...
    }
  }
}

Example: Retrieve a current_totals report for all users on an account.

Request Body

{
  "data": {
    "on_the_clock": "both"
  }
}

Request

curl -X POST \
  https://rest.tsheets.com/api/v1/reports/current_totals \
  -H 'Authorization: Bearer <TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '<REQUEST BODY>'
var client = new RestClient("https://rest.tsheets.com/api/v1/reports/current_totals");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <TOKEN>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "<REQUEST BODY>", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/reports/current_totals")
Dim request = New RestRequest(Method.POST)
request.AddHeader("Authorization", "Bearer <TOKEN>")
request.AddHeader("Content-Type", "application/json")
request.AddParameter("application/json", "<REQUEST BODY>", ParameterType.RequestBody);
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<REQUEST BODY>");
Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/reports/current_totals")
  .post(body)
  .addHeader("Authorization", "Bearer <TOKEN>")
  .addHeader("Content-Type", "application/json")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/reminders?user_ids=0,37&reminder_types=clock-in&modified_since=2018-07-15T19:32:00-06:00",
  "method": "POST",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
    "Content-Type", "application/json",
  },
  "processData": false,
  "data": "<REQUEST BODY>"
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'POST',
  url: 'https://rest.tsheets.com/api/v1/reports/current_totals',
  headers: 
  { 
     'Authorization': 'Bearer <TOKEN>',
     'Content-Type': 'application/json',
  },
  body: '<REQUEST BODY>',
  json: true };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/reports/current_totals');
$request->setMethod(HTTP_METH_POST);

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
  'Content-Type' => 'application/json',
));

$request->setBody('<REQUEST BODY>');

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/reports/current_totals")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <TOKEN>',
request["Content-Type"] = 'application/json',
request.body = "<REQUEST BODY>"

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/reports/current_totals"

payload = "<REQUEST BODY>"
headers = {
    'Authorization': 'Bearer <TOKEN>',
    'Content-Type': 'application/json',
    }

response = requests.request("POST", url, data=payload, headers=headers)

print(response.text)
package main

import (
  "fmt"
  "strings"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/reports/current_totals"

  payload := strings.NewReader("<REQUEST BODY>")

  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, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))

}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
   "Content-Type": "application/json",
]
let parameters = <REQUEST BODY> as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/reports/current_totals")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest,
  completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');
$client->addHeader('Content-Type', 'application/json');

$req = '<REQUEST BODY>';

$url="https://rest.tsheets.com/api/v1/reports/current_totals"; 

$client->POST($url, $req);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "current_totals": {
      "1751136": {
        "user_id": 1751136,
        "on_the_clock": true,
        "timesheet_id": 173523290,
        "jobcode_id": 26730062,
        "group_id": 180010,
        "shift_geolocations_available": true,
        "shift_seconds": 25275,
        "day_seconds": 25275
      },
      "1738864": {
        "user_id": 1738864,
        "on_the_clock": false,
        "timesheet_id": null,
        "jobcode_id": null,
        "group_id": 180010,
        "shift_geolocations_available": false,
        "shift_seconds": 0,
        "day_seconds": 25719
      },
      ...
    }
  },
  "supplemental_data": {
    "users": {
      "1751136": {
        "id": 1751136,
        "first_name": "Leeroy",
        "last_name": "Jenkins",
        "group_id": 180010,
        "active": true,
        ...
      },
      ...
    },
    "groups": {
      "0": {
        "id": 0,
        "name": "-",
        "last_modified": "2018-02-11T17:48:39+00:00",
        "created": "2018-02-11T17:47:04+00:00"
      },
      ...
    },
    "timesheets": {
      "173523280": {
        "id": 173523280,
        "user_id": 1751140,
        "jobcode_id": 26730062,
        "start": "2018-11-03T09:07:21-07:00",
        "end": "",
        ...
      },
      ...
    },
    "jobcodes": {
      "26730062": {
        "id": 26730062,
        "parent_id": 26730016,
        "assigned_to_all": false,
        "billable": false,
        "active": true,
        "type": "regular",
        ...
      }
    }
  }
}

Retrieves a snapshot report for the current totals (shift and day) along with additional information provided for those who are currently on the clock.

HTTP Request

posthttps://rest.tsheets.com/api/v1/reports/current_totals

Filter Properties

Pass an an object of filters as the value to a 'data' property (see example).

user_ids
optional
Int A comma-separated list of user ids. Only totals for these users will be included.
group_ids
optional
Int A comma-separated list of group ids. Only totals for users from these groups will be included.
on_the_clock
optional
String 'yes', 'no', or 'both'. Default is 'no'. If a user is on_the_clock, it means the user is currently working (has not clocked out yet).
page
optional
Int Represents the page of results you'd like to retrieve. Default is 1.
per_page
optional
Int Deprecated. Use limit for new code.
Represents how many results you'd like to retrieve per request. Default is 50. Max is 50.
If a value over 50 is provided, it is ignored, and the max is used.
limit
optional
Int Represents how many results you'd like to retrieve per request. Default is 200. Max is 200.
If present, this value must be: an integer, greater than zero, and not greater than 200.
Setting limit less than 1 or greater than 200 will result in an error.
order_by
optional
String Attribute name by which to order the result data, one of: 'username', 'first_name', 'last_name', 'group_name', 'group_id', 'shift_seconds', or 'day_seconds'.
order_desc
optional
Boolean Either true or false. If true, result data will be ordered descending by the attribute specified in the order_by filter.

Understanding the Output

See explanation of response layout to the right.

Retrieve Payroll Report

Response Layout

{
  "results": {
    "payroll_report": {
      "191544": {                    # Indexed by user_id
        "user_id": 191544,
        "client_id": "183",
        "start_date": "2019-03-02",  # Start of reporting timeframe.
        "end_date": "2019-03-15",    # End of the payroll reporting timeframe.
        "total_re_seconds": 1816,    # Regular time, in seconds.
        "total_ot_seconds": 0,       # Overtime, in seconds.
        "total_dt_seconds": 0,       # Doubletime, in seconds.
        "total_pto_seconds": 7200,   # Total PTO time, in seconds.
        "total_work_seconds": 1816,  # Total overall time, in seconds.
        "pto_seconds": {             # Break-down of PTO time by PTO code.
          "123876": 7200             # Indexed by PTO code id, then value is 
        }                            #   the time, in seconds.
      }
    }
  }
}

The format with advanced overtime is as follows:

{
  "results": {
    "payroll_report": {
      "191549": {                    # Indexed by user_id.
        "user_id": 191549,
        "client_id": "188",
        "start_date": "2019-03-02",  # Start of the reporting timeframe.
        "end_date": "2019-03-15",    # End of the reporting timeframe.
        "total_re_seconds": 1816,    # Regular time, in seconds.
        "total_pto_seconds": 7200,   # Total PTO time, in seconds.
        "total_work_seconds": 5416,  # Total overall time, in seconds.
        "pto_seconds": {             # Break-down of PTO time by PTO code.
          "123876": 7200             # Indexed by PTO code id, then value is 
        },                           #   the time, in seconds.
        "overtime_seconds": {        # This replaces total_ot_seconds
          "1.6": 3600,               #   and total_dt_seconds.
          "3" : 0
        },
        "fixed_rate_seconds": {
          "2": 3600,                 # Fixed rate time is listed here.
          "5": 7200                  # The overtime_seconds section above is
        }                            #   for multiplier rates.
      },
      "31174": {
        "user_id": 31174,
        "client_id": "188",
        "start_date": "2019-03-02",
        "end_date": "2019-03-15",
        "total_re_seconds": 28800,
        "total_pto_seconds": 0,
        "total_work_seconds": 606845,
        "pto_seconds": {}
        "overtime_seconds": {          # With the Overtime add-on, different
          "1.5": 14400,                # rates can apply to different people 
          "2" : 563645                 # So 1.5x & 2x instead of 1.6x & 3x. 
         },
        "fixed_rate_seconds" : {}    
      }
    }
  }
}

Example: Retrieve a payroll report for a given time period for all users on an account.

Request Body

{
 "data":
  {
    "start_date": "2018-03-02",
    "end_date": "2018-03-15",
    "advanced_overtime": "no"
  }
}

Request

curl -X POST \
  https://rest.tsheets.com/api/v1/reports/payroll \
  -H 'Authorization: Bearer <TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '<REQUEST BODY>'
var client = new RestClient("https://rest.tsheets.com/api/v1/reports/payroll");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <TOKEN>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "<REQUEST BODY>", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/reports/payroll")
Dim request = New RestRequest(Method.POST)
request.AddHeader("Authorization", "Bearer <TOKEN>")
request.AddHeader("Content-Type", "application/json")
request.AddParameter("application/json", "<REQUEST BODY>", ParameterType.RequestBody);
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<REQUEST BODY>");
Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/reports/payroll")
  .post(body)
  .addHeader("Authorization", "Bearer <TOKEN>")
  .addHeader("Content-Type", "application/json")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/reminders?user_ids=0,37&reminder_types=clock-in&modified_since=2018-07-15T19:32:00-06:00",
  "method": "POST",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
    "Content-Type", "application/json",
  },
  "processData": false,
  "data": "<REQUEST BODY>"
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'POST',
  url: 'https://rest.tsheets.com/api/v1/reports/payroll',
  headers: 
  { 
     'Authorization': 'Bearer <TOKEN>',
     'Content-Type': 'application/json',
  },
  body: '<REQUEST BODY>',
  json: true };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/reports/payroll');
$request->setMethod(HTTP_METH_POST);

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
  'Content-Type' => 'application/json',
));

$request->setBody('<REQUEST BODY>');

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/reports/payroll")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <TOKEN>',
request["Content-Type"] = 'application/json',
request.body = "<REQUEST BODY>"

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/reports/payroll"

payload = "<REQUEST BODY>"
headers = {
    'Authorization': 'Bearer <TOKEN>',
    'Content-Type': 'application/json',
    }

response = requests.request("POST", url, data=payload, headers=headers)

print(response.text)
package main

import (
  "fmt"
  "strings"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/reports/payroll"

  payload := strings.NewReader("<REQUEST BODY>")

  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, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))

}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
   "Content-Type": "application/json",
]
let parameters = <REQUEST BODY> as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/reports/payroll")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest,
  completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');
$client->addHeader('Content-Type', 'application/json');

$req = '<REQUEST BODY>';

$url="https://rest.tsheets.com/api/v1/reports/payroll"; 

$client->POST($url, $req);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "payroll_report": {
      "191544": {
        "user_id": 191544,
        "client_id": "183",
        "start_date": "2018-03-02",
        "end_date": "2018-03-15",
        "total_re_seconds": 1816,
        "total_ot_seconds": 0,
        "total_dt_seconds": 0,
        "total_pto_seconds": 0,
        "total_work_seconds": 1816,
        "pto_seconds": {}
      },
      "31174": {
        "user_id": 31174,
        "client_id": "183",
        "start_date": "2018-03-02",
        "end_date": "2018-03-15",
        "total_re_seconds": 28800,
        "total_ot_seconds": 14400,
        "total_dt_seconds": 563645,
        "total_pto_seconds": 0,
        "total_work_seconds": 606845,
        "pto_seconds": {}
      },
      "15004": {
        "user_id": 15004,
        "client_id": "183",
        "start_date": "2018-03-02",
        "end_date": "2018-03-15",
        "total_re_seconds": 1819,
        "total_ot_seconds": 0,
        "total_dt_seconds": 0,
        "total_pto_seconds": 0,
        "total_work_seconds": 1819,
        "pto_seconds": {}
      },
      "29494": {
        "user_id": 29494,
        "client_id": "183",
        "start_date": "2018-03-02",
        "end_date": "2018-03-15",
        "total_re_seconds": 1806,
        "total_ot_seconds": 0,
        "total_dt_seconds": 0,
        "total_pto_seconds": 0,
        "total_work_seconds": 1806,
        "pto_seconds": {}
      },
      "29504": {
        "user_id": 29504,
        "client_id": "183",
        "start_date": "2018-03-02",
        "end_date": "2018-03-15",
        "total_re_seconds": 1815,
        "total_ot_seconds": 0,
        "total_dt_seconds": 0,
        "total_pto_seconds": 0,
        "total_work_seconds": 1815,
        "pto_seconds": {}
      },
      "29604": {
        "user_id": 29604,
        "client_id": "183",
        "start_date": "2018-03-02",
        "end_date": "2018-03-15",
        "total_re_seconds": 275,
        "total_ot_seconds": 0,
        "total_dt_seconds": 0,
        "total_pto_seconds": 28800,
        "total_work_seconds": 29075,
        "pto_seconds": {
          "12074": 28800
        }
      }
    }
  },
  "supplemental_data": {
    "users": {
      "191544": {
        "id": 191544,
        "first_name": "Harrison",
        "last_name": "Ford",
        "group_id": 4124,
        "active": true,
        ...
      }
    },
    "jobcodes": {
      "12074": {
        "id": 12074,
        "parent_id": 0,
        "assigned_to_all": false,
        "billable": false,
        "active": true,
        "type": "pto",
        ...
      }
    }
  }
}

Retrieves a payroll report associated with a timeframe, with filters to narrow down the results.

HTTP Request

posthttps://rest.tsheets.com/api/v1/reports/payroll

Filter Properties

Pass an an object of filters as the value to a 'data' property (see example).

start_date
required
String YYYY-MM-DD formatted date. Any time with a date falling on or after this date will be included.
end_date
required
String YYYY-MM-DD formatted date. Any time with a date falling on or before this date will be included.
user_ids
optional
Int A comma-separated list of user ids. Only time for these users will be included.
group_ids
optional
Int A comma-seperated list of group ids. Only time for users from these groups will be included.
include_zero_time
optional
String 'yes' or 'no'. Default is 'no'. If 'yes', all users will be included in the output, even if they had zero hours for the time period.
advanced_overtime
optional
String 'yes' or 'no'. If 'yes', overtime will be formatted such that it includes the time for individual multipliers and can support more than just 1.5x (ot) and 2x (dt) overtime.

Note: For advanced_overtime the default for api keys created before Oct 25th 2017 is 'no', however, the default for api keys created after this date is 'yes' and attempting to pass this parameter with a value of 'no' will result in an exception.

Note: The advanced_overtime setting is required to be passed as 'yes' if the Overtime add-on is installed and rates other than the standard 1.5x and 2x rates are defined. This is enforced so that incorrect overtime values that do not comply with the standard "total_ot_seconds" (1.5x) and "total_dt_seconds" (2x) rates are not missed.

Understanding the Output

See explanation of response layouts to the right.

Notice in the advanced overtime layout that the total_ot_seconds and total_dt_seconds values have been replaced by the overtime_seconds and fixed_rate_seconds objects in each instance. In the overtime_seconds object the key is the multiplier rate and the value is the number of seconds of overtime at that rate (i.e 14400 seconds at 1.5x). In the fixed_rate_seconds object, the key is the additional rate amount to add to the employee's hourly rate and the value is the time in seconds.

Retrieve Payroll by Jobcode Report

Response Layout

{
  "results": {
    "filters": {                       # The parameters (passed to the API).
      "start_date": "2019-03-12",      # Start date for the report.
      "end_date": "2019-03-18",        # End date for the report.
      "user_ids": [                    # Array of user IDs to include in the
        "15790",                       #   report. If not present, all users
        "76108",                       #   will be included.
        "76124"
      ]
    },
    "payroll_by_jobcode_report": {     # The report section of the output.
      "totals": {                      # Overall totals for each jobcode
                                       #   contained in the report.
        "82026": {                     # Jobcode ID.
          "jobcode_id": 82026,     
          "total_re_seconds": 0,       # Total regular seconds for this jobcode.
          "total_ot_seconds": 0,       # Total overtime seconds for this jobcode.
          "total_dt_seconds": 0,       # Total double time seconds for this jobcode.
          "total_pto_seconds": 28800,  # Total PTO seconds for this jobcode.
          "total_work_seconds": 28800  # Total number of seconds for this jobcode.
        },                     
        "733512": {
          "jobcode_id": 733512,
          "total_re_seconds": 57600,
          "total_ot_seconds": 18300,
          "total_dt_seconds": 0,
          "total_pto_seconds": 0,
          "total_work_seconds": 75900
        }
      },
      "by_user": {                     # Totals Section (by user).
        "15790": {                     # User ID.
          "user_id": 15790,             
          "totals": {                  # Totals for each jobcode, for this user.
            "82026": {                 # Jobcode ID.
              "jobcode_id": 82026,         
              "total_re_seconds": 0,
              "total_ot_seconds": 0,
              "total_dt_seconds": 0,
              "total_pto_seconds": 28800,
              "total_work_seconds": 28800
            },
            "733512": {
              "jobcode_id": 733512,
              "total_re_seconds": 57600,
              "total_ot_seconds": 18300,
              "total_dt_seconds": 0,
              "total_pto_seconds": 0,
              "total_work_seconds": 75900
            }
          },
          "dates": {                   # Totals by Date (for this user).
            "2019-03-15": {            # Date.
              "82026": {               # Jobcode ID.
                "jobcode_id": 82026,        
                "total_re_seconds": 0,
                "total_ot_seconds": 0,
                "total_dt_seconds": 0,
                "total_pto_seconds": 28800,
                "total_unpaid_seconds": 0,
                "total_work_seconds": 28800
              },
              "733512": {
                "jobcode_id": 733512,
                "total_re_seconds": 28800,
                "total_ot_seconds": 8340,
                "total_dt_seconds": 0,
                "total_pto_seconds": 0,
                "total_unpaid_seconds": 0,
                "total_work_seconds": 37140
              }
            }
          }
        } 
      }
    }
  }
}

The format with advanced overtime is as follows:

{
  "results": {
    "filters": {                        # The parameters (passed to the API).
      "start_date": "2017-03-12",       # Start date for the report.
      "end_date": "2017-03-18",         # End date for the report.
      "user_ids": [                     # Array of user IDs to include in the
        "15790",                        #   report. If not present, all users
        "76108",                        #   will be included.
        "76124"
      ]
    },
    "payroll_by_jobcode_report": {      # The report section of the output
      "totals": {                       # Overall totals for each jobcode
                                        #   contained in the report.
        "82026": {                      # Jobcode ID
          "jobcode_id": 82026,           
          "total_re_seconds": 10800     # Total regular seconds for this jobcode.
          "total_pto_seconds": 28800,   # Total PTO seconds for this jobcode.
          "total_work_seconds": 28800,  # Total number of seconds for this jobcode.
          "overtime_seconds": {         # This replaces "total_ot_seconds" 
            "1.6": 0,                   #   and "total_dt_seconds".
            "3" : 0
          },
          "fixed_rate_seconds": {
            "2": 3600,                  # Fixed rate time is listed here.
            "4": 7200                   # The overtime_seconds section above
          }                             #   is for multiplier rates.
        },                     
        "733512": {
          "jobcode_id": 733512,
          "total_re_seconds": 57600,
          "total_pto_seconds": 0,
          "total_work_seconds": 75900
          "overtime_seconds": {           
            "1.6": 18300,                
            "3" : 0
          },
          "fixed_rate_seconds": {}      
        }
      },
      "by_user": {                      # Totals Section (by user)
        "15790": {                      # User ID
          "user_id": 15790,             
          "totals": {                   # Totals for each jobcode, for this user.
            "82026": {                  # Jobcode ID
              "jobcode_id": 82026,         
              "total_re_seconds": 10800,
              "total_pto_seconds": 28800,
              "total_work_seconds": 28800
              "overtime_seconds": {           
                "1.6": 0,                
                "3" : 0
              },
              "fixed_rate_seconds": {
                "2": 3600,
                "4": 7200
              }       
            },
            "733512": {
              "jobcode_id": 733512,
              "total_re_seconds": 57600,
              "total_pto_seconds": 0,
              "total_work_seconds": 75900
              "overtime_seconds": {           
                "1.6": 18300,                
                "3" : 0
              },
              "fixed_rate_seconds": {}      
            }
          },
          "dates": {                    # Totals by Date (for this user)
            "2017-03-15": {             # Date
              "82026": {                # Jobcode ID
                "jobcode_id": 82026,        
                "total_re_seconds": 10800,
                "total_pto_seconds": 28800,
                "total_unpaid_seconds": 0,
                "total_work_seconds": 28800
                "overtime_seconds": {           
                  "1.6": 0,                
                  "3" : 0
                },
                "fixed_rate_seconds": {
                  "2": 3600,
                  "4": 7200
                }      
              },
              "733512": {
                "jobcode_id": 733512,
                "total_re_seconds": 28800,
                "total_pto_seconds": 0,
                "total_unpaid_seconds": 0,
                "total_work_seconds": 37140
                "overtime_seconds": {           
                  "1.6": 8340,                
                  "3" : 0
                },
                "fixed_rate_seconds": {}      
              }
            }
          }
        }
      }
    }
  }
}

Example: Retrieve a payroll report, broken down by jobcode, for the given time period within an account.

Request Body

{
  "data": {
    "user_ids": "15790,76108,76124",
    "start_date": "2018-03-12",
    "end_date": "2018-03-18",
    "advanced_overtime": "no"
  }
}

Request

curl -X POST \
  https://rest.tsheets.com/api/v1/reports/payroll_by_jobcode \
  -H 'Authorization: Bearer <TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '<REQUEST BODY>'
var client = new RestClient("https://rest.tsheets.com/api/v1/reports/payroll_by_jobcode");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <TOKEN>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "<REQUEST BODY>", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/reports/payroll_by_jobcode")
Dim request = New RestRequest(Method.POST)
request.AddHeader("Authorization", "Bearer <TOKEN>")
request.AddHeader("Content-Type", "application/json")
request.AddParameter("application/json", "<REQUEST BODY>", ParameterType.RequestBody);
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<REQUEST BODY>");
Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/reports/payroll_by_jobcode")
  .post(body)
  .addHeader("Authorization", "Bearer <TOKEN>")
  .addHeader("Content-Type", "application/json")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/reminders?user_ids=0,37&reminder_types=clock-in&modified_since=2018-07-15T19:32:00-06:00",
  "method": "POST",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
    "Content-Type", "application/json",
  },
  "processData": false,
  "data": "<REQUEST BODY>"
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'POST',
  url: 'https://rest.tsheets.com/api/v1/reports/payroll_by_jobcode',
  headers: 
  { 
     'Authorization': 'Bearer <TOKEN>',
     'Content-Type': 'application/json',
  },
  body: '<REQUEST BODY>',
  json: true };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/reports/payroll_by_jobcode');
$request->setMethod(HTTP_METH_POST);

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
  'Content-Type' => 'application/json',
));

$request->setBody('<REQUEST BODY>');

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/reports/payroll_by_jobcode")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <TOKEN>',
request["Content-Type"] = 'application/json',
request.body = "<REQUEST BODY>"

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/reports/payroll_by_jobcode"

payload = "<REQUEST BODY>"
headers = {
    'Authorization': 'Bearer <TOKEN>',
    'Content-Type': 'application/json',
    }

response = requests.request("POST", url, data=payload, headers=headers)

print(response.text)
package main

import (
  "fmt"
  "strings"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/reports/payroll_by_jobcode"

  payload := strings.NewReader("<REQUEST BODY>")

  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, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))

}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
   "Content-Type": "application/json",
]
let parameters = <REQUEST BODY> as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/reports/payroll_by_jobcode")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest,
  completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');
$client->addHeader('Content-Type', 'application/json');

$req = '<REQUEST BODY>';

$url="https://rest.tsheets.com/api/v1/reports/payroll_by_jobcode"; 

$client->POST($url, $req);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "filters": {
      "start_date": "2017-03-12",
      "end_date": "2017-03-18",
      "user_ids": [
        "15790",
        "76108",
        "76124"
      ]
    },
    "payroll_by_jobcode_report": {
      "totals": {
        "82024": {
          "jobcode_id": 82024,
          "total_re_seconds": 0,
          "total_ot_seconds": 0,
          "total_dt_seconds": 0,
          "total_pto_seconds": 14400,
          "total_work_seconds": 14400
        },
        "82026": {
          "jobcode_id": 82026,
          "total_re_seconds": 0,
          "total_ot_seconds": 0,
          "total_dt_seconds": 0,
          "total_pto_seconds": 28800,
          "total_work_seconds": 28800
        },
        "762436": {
          "jobcode_id": 762436,
          "total_re_seconds": 0,
          "total_ot_seconds": 0,
          "total_dt_seconds": 0,
          "total_pto_seconds": 28800,
          "total_work_seconds": 28800
        }
      },
      "by_user": {
        "15790": {
          "user_id": 15790,
          "totals": {
            "82026": {
              "jobcode_id": 82026,
              "total_re_seconds": 0,
              "total_ot_seconds": 0,
              "total_dt_seconds": 0,
              "total_pto_seconds": 28800,
              "total_work_seconds": 28800
            },
            "733512": {
              "jobcode_id": 733512,
              "total_re_seconds": 57600,
              "total_ot_seconds": 18300,
              "total_dt_seconds": 0,
              "total_pto_seconds": 0,
              "total_work_seconds": 75900
            },
            "733514": {
              "jobcode_id": 733514,
              "total_re_seconds": 28800,
              "total_ot_seconds": 12480,
              "total_dt_seconds": 0,
              "total_pto_seconds": 0,
              "total_work_seconds": 41280
            },
            "733516": {
              "jobcode_id": 733516,
              "total_re_seconds": 28800,
              "total_ot_seconds": 3360,
              "total_dt_seconds": 0,
              "total_pto_seconds": 0,
              "total_work_seconds": 32160
            },
            "733528": {
              "jobcode_id": 733528,
              "total_re_seconds": 28800,
              "total_ot_seconds": 14400,
              "total_dt_seconds": 0,
              "total_pto_seconds": 0,
              "total_work_seconds": 43200
            }
          },
          "dates": {
            "2017-03-13": {
              "733528": {
                "jobcode_id": 733528,
                "total_re_seconds": 28800,
                "total_ot_seconds": 14400,
                "total_dt_seconds": 0,
                "total_pto_seconds": 0,
                "total_unpaid_seconds": 0,
                "total_work_seconds": 43200
              }
            },
            "2017-03-14": {
              "733516": {
                "jobcode_id": 733516,
                "total_re_seconds": 28800,
                "total_ot_seconds": 3360,
                "total_dt_seconds": 0,
                "total_pto_seconds": 0,
                "total_unpaid_seconds": 0,
                "total_work_seconds": 32160
              }
            },
            "2017-03-15": {
              "82026": {
                "jobcode_id": 82026,
                "total_re_seconds": 0,
                "total_ot_seconds": 0,
                "total_dt_seconds": 0,
                "total_pto_seconds": 28800,
                "total_unpaid_seconds": 0,
                "total_work_seconds": 28800
              },
              "733512": {
                "jobcode_id": 733512,
                "total_re_seconds": 28800,
                "total_ot_seconds": 8340,
                "total_dt_seconds": 0,
                "total_pto_seconds": 0,
                "total_unpaid_seconds": 0,
                "total_work_seconds": 37140
              }
            },
            "2017-03-16": {
              "733514": {
                "jobcode_id": 733514,
                "total_re_seconds": 28800,
                "total_ot_seconds": 12480,
                "total_dt_seconds": 0,
                "total_pto_seconds": 0,
                "total_unpaid_seconds": 0,
                "total_work_seconds": 41280
              }
            },
            "2017-03-17": {
              "733512": {
                "jobcode_id": 733512,
                "total_re_seconds": 28800,
                "total_ot_seconds": 9960,
                "total_dt_seconds": 0,
                "total_pto_seconds": 0,
                "total_unpaid_seconds": 0,
                "total_work_seconds": 38760
              }
            }
          }
        },
        "76108": {
          "user_id": 76108,
          "totals": {
            "733512": {
              "jobcode_id": 733512,
              "total_re_seconds": 18960,
              "total_ot_seconds": 0,
              "total_dt_seconds": 0,
              "total_pto_seconds": 0,
              "total_work_seconds": 18960
            },
            "733516": {
              "jobcode_id": 733516,
              "total_re_seconds": 8700,
              "total_ot_seconds": 0,
              "total_dt_seconds": 0,
              "total_pto_seconds": 0,
              "total_work_seconds": 8700
            },
            "762436": {
              "jobcode_id": 762436,
              "total_re_seconds": 0,
              "total_ot_seconds": 0,
              "total_dt_seconds": 0,
              "total_pto_seconds": 28800,
              "total_work_seconds": 28800
            }
          },
          "dates": {
            "2017-03-13": {
              "733512": {
                "jobcode_id": 733512,
                "total_re_seconds": 18960,
                "total_ot_seconds": 0,
                "total_dt_seconds": 0,
                "total_pto_seconds": 0,
                "total_unpaid_seconds": 0,
                "total_work_seconds": 18960
              }
            },
            "2017-03-14": {
              "733516": {
                "jobcode_id": 733516,
                "total_re_seconds": 8700,
                "total_ot_seconds": 0,
                "total_dt_seconds": 0,
                "total_pto_seconds": 0,
                "total_unpaid_seconds": 0,
                "total_work_seconds": 8700
              }
            },
            "2017-03-15": {
              "762436": {
                "jobcode_id": 762436,
                "total_re_seconds": 0,
                "total_ot_seconds": 0,
                "total_dt_seconds": 0,
                "total_pto_seconds": 28800,
                "total_unpaid_seconds": 0,
                "total_work_seconds": 28800
              }
            }
          }
        },
        "76124": {
          "user_id": 76124,
          "totals": {
            "82024": {
              "jobcode_id": 82024,
              "total_re_seconds": 0,
              "total_ot_seconds": 0,
              "total_dt_seconds": 0,
              "total_pto_seconds": 14400,
              "total_work_seconds": 14400
            },
            "733516": {
              "jobcode_id": 733516,
              "total_re_seconds": 144000,
              "total_ot_seconds": 28800,
              "total_dt_seconds": 3600,
              "total_pto_seconds": 0,
              "total_work_seconds": 176400
            }
          },
          "dates": {
            "2017-03-13": {
              "733516": {
                "jobcode_id": 733516,
                "total_re_seconds": 28800,
                "total_ot_seconds": 0,
                "total_dt_seconds": 0,
                "total_pto_seconds": 0,
                "total_unpaid_seconds": 0,
                "total_work_seconds": 28800
              }
            },
            "2017-03-14": {
              "733516": {
                "jobcode_id": 733516,
                "total_re_seconds": 28800,
                "total_ot_seconds": 14400,
                "total_dt_seconds": 3600,
                "total_pto_seconds": 0,
                "total_unpaid_seconds": 0,
                "total_work_seconds": 46800
              }
            },
            "2017-03-15": {
              "82024": {
                "jobcode_id": 82024,
                "total_re_seconds": 0,
                "total_ot_seconds": 0,
                "total_dt_seconds": 0,
                "total_pto_seconds": 14400,
                "total_unpaid_seconds": 0,
                "total_work_seconds": 14400
              },
              "733516": {
                "jobcode_id": 733516,
                "total_re_seconds": 28800,
                "total_ot_seconds": 0,
                "total_dt_seconds": 0,
                "total_pto_seconds": 0,
                "total_unpaid_seconds": 0,
                "total_work_seconds": 28800
              }
            },
            "2017-03-16": {
              "733516": {
                "jobcode_id": 733516,
                "total_re_seconds": 28800,
                "total_ot_seconds": 14400,
                "total_dt_seconds": 0,
                "total_pto_seconds": 0,
                "total_unpaid_seconds": 0,
                "total_work_seconds": 43200
              }
            },
            "2017-03-17": {
              "733516": {
                "jobcode_id": 733516,
                "total_re_seconds": 28800,
                "total_ot_seconds": 0,
                "total_dt_seconds": 0,
                "total_pto_seconds": 0,
                "total_unpaid_seconds": 0,
                "total_work_seconds": 28800
              }
            }
          }
        }
      }
    }
  },
  "supplemental_data": {
    "users": {
      "15790": {
        "id": 15790,
        "first_name": "Adam",
        "last_name": "Ashton",
        "group_id": 1648,
        "active": true,
        ...
      },
      "76108": {
        "id": 76108,
        "first_name": "Alison",
        "last_name": "Canseco",
        "group_id": 0,
        "active": true,
        ...
      },
      ...
    },
    "jobcodes": {
      "82024": {
        "id": 82024,
        "parent_id": 0,
        "assigned_to_all": true,
        "billable": false,
        "active": true,
        ...
      },
      "82026": {
        "id": 82026,
        "parent_id": 0,
        "assigned_to_all": true,
        "billable": false,
        "active": true,
        ...
      },
      ...
    }
  }
}

Retrieves a payroll report, broken down by jobcode, with filters to narrow down the results.

Overtime (and double time) are allocated based on the jobcode they are working on at the time the thresholds are crossed. In other words, by order of occurrence.

As an example, assume that an employee works 60 hours against 3 different job codes, following this schedule: 25 hours against jobcode A, then 25 hours against jobcode B, then 10 hours against jobcode C. The report would allocate the time as follows:

Jobcode Hours Regular Overtime
A 25 25 0
B 25 15 10
C 10 0 10

HTTP Request

posthttps://rest.tsheets.com/api/v1/reports/payroll_by_jobcode

Filter Properties

Pass an an object of filters as the value to a 'data' property (see example).

start_date
required
String YYYY-MM-DD formatted date. Any time with a date falling on or after this date will be included.
end_date
required
String YYYY-MM-DD formatted date. Any time with a date falling on or before this date will be included.
user_ids
optional
Int A comma-separated list of user ids. Only time for these users will be included.
group_ids
optional
Int A comma-separated list of group ids. Only time for users from these groups will be included.
advanced_overtime
optional
String 'yes' or 'no'. If 'yes', overtime will be formatted such that it includes the time for individual multipliers and can support more than just 1.5x (ot) and 2x (dt) overtime.

Note: For advanced_overtime the default for api keys created before Oct 25th 2017 is 'no', however, the default for api keys created after this date is 'yes' and attempting to pass this parameter with a value of 'no' will result in an exception.

Note: The advanced_overtime setting is required to be passed as 'yes' if the Overtime add-on is installed and rates other than the standard 1.5x and 2x rates are defined. This is enforced so that incorrect overtime values that do not comply with the standard "total_ot_seconds" (1.5x) and "total_dt_seconds" (2x) rates are not missed.

Understanding the Output

See explanation of response layouts to the right.

Notice in the advanced overtime layout that the total_ot_seconds and total_dt_seconds values have been replaced by the overtime_seconds and fixed_rate_seconds objects in each instance. In the overtime_seconds object the key is the multiplier rate and the value is the number of seconds of overtime at that rate (i.e 8340 seconds at 1.5x). In the fixed_rate_seconds object, the key is the additional rate amount to add to the employee's hourly rate and the value is the time in seconds.

Retrieve Project Estimate Reports

Response Layout

  {
  "results": {
    "279": {
        "id": 279,
        "jobcode_id": 48979,
        "parent_jobcode_id": 48959,
        "name": "Installing tires",
        "status": "in_progress",
        "description": "All four wheels and tires need to be installed, aligned. ",
        "start_date": "2020-03-03",
        "due_date": "2020-03-06",
        "completed_date": "",
        "active": 1,
        "last_modified": "2020-03-02T17:19:12+00:00",
        "created": "2020-03-02T17:19:12+00:00",
                        ## See the estimate object for more information on the following estimate attributes. 
                        ## The total number of estimated seconds for the project. If the estimate has many estimate items, 
                        ## total_estimated_seconds is the sum of all the items.
        "estimate_id": 5,
                        ## The estimate type associated with the project. Possible values are "none" or "customfields".
                        ## If the project does not have an estimate, the value will be null.
        "estimate_by": "customfields",
                        ## The customfield id being estimated by if "estimate_by" is "customfields". Null otherwise.
        "estimate_by__id": 0,
                        ## The total tracked seconds on the project.
        "total_clocked_in_seconds": 0,
        "total_clocked_out_seconds": 12327,
        "total_tracked_seconds": 12327,
        "total_estimated_seconds": 90000,
        "total_note_count": 0,
        "unread_posts_count": 0,
        "unread_replies_count": 0,
        "budget_progress": 0.14000000000000001,
        "clocked_in_user_ids": []
    }
  }
}

Example: Retrieve a project estimate report for time recorded for a project.

Request Body

{
    "data":
    {
        "project_ids": [12345, 54321],
        "active": "yes",
        "page": 1,
        "limit": 2,
        "supplemental_data": "no",
        "results_as_array": "no"
    }
}



Request

curl -X POST \
  https://rest.tsheets.com/api/v1/reports/project_estimate \
  -H 'Authorization: Bearer <TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '<REQUEST BODY>'
var client = new RestClient("https://rest.tsheets.com/api/v1/reports/project_estimate");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <TOKEN>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "<REQUEST BODY>", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/reports/project_estimate")
Dim request = New RestRequest(Method.POST)
request.AddHeader("Authorization", "Bearer <TOKEN>")
request.AddHeader("Content-Type", "application/json")
request.AddParameter("application/json", "<REQUEST BODY>", ParameterType.RequestBody);
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<REQUEST BODY>");
Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/reports/project_estimate")
  .post(body)
  .addHeader("Authorization", "Bearer <TOKEN>")
  .addHeader("Content-Type", "application/json")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/reminders?user_ids=0,37&reminder_types=clock-in&modified_since=2018-07-15T19:32:00-06:00",
  "method": "POST",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
    "Content-Type", "application/json",
  },
  "processData": false,
  "data": "<REQUEST BODY>"
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'POST',
  url: 'https://rest.tsheets.com/api/v1/reports/project_estimate',
  headers: 
  { 
     'Authorization': 'Bearer <TOKEN>',
     'Content-Type': 'application/json',
  },
  body: '<REQUEST BODY>',
  json: true };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/reports/project_estimate');
$request->setMethod(HTTP_METH_POST);

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
  'Content-Type' => 'application/json',
));

$request->setBody('<REQUEST BODY>');

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/reports/project_estimate")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <TOKEN>',
request["Content-Type"] = 'application/json',
request.body = "<REQUEST BODY>"

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/reports/project_estimate"

payload = "<REQUEST BODY>"
headers = {
    'Authorization': 'Bearer <TOKEN>',
    'Content-Type': 'application/json',
    }

response = requests.request("POST", url, data=payload, headers=headers)

print(response.text)
package main

import (
  "fmt"
  "strings"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/reports/project_estimate"

  payload := strings.NewReader("<REQUEST BODY>")

  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, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))

}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
   "Content-Type": "application/json",
]
let parameters = <REQUEST BODY> as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/reports/project_estimate")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest,
  completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');
$client->addHeader('Content-Type', 'application/json');

$req = '<REQUEST BODY>';

$url="https://rest.tsheets.com/api/v1/reports/project_estimate"; 

$client->POST($url, $req);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
    "filters": {
        "page": 1,
        "limit": 2,
        "project_ids": [],
        "statuses": [],
        "parent_jobcode_id": "",
        "jobcode_ids": "",
        "active": true,
        "search": [],
        "has_time_tracked": false,
        "time_tracked_start_date": null,
        "time_tracked_end_date": null
    },
    "more": true,
    "total_count": 8,
    "results": {
        "279": {
            "id": 279,
            "jobcode_id": 48979,
            "parent_jobcode_id": 48959,
            "name": "Installing tires",
            "status": "in_progress",
            "description": "All four wheels and tires need to be installed, aligned. ",
            "start_date": "2020-03-03",
            "due_date": "2020-03-06",
            "completed_date": "",
            "active": 1,
            "last_modified": "2020-03-02T17:19:12+00:00",
            "created": "2020-03-02T17:19:12+00:00",
            "estimate_id": 5,
            "estimate_by": "none",
            "estimate_by__id": 0,
            "total_clocked_in_seconds": 0,
            "total_clocked_out_seconds": 12327,
            "total_tracked_seconds": 12327,
            "total_estimated_seconds": 90000,
            "total_note_count": 0,
            "unread_posts_count": 0,
            "unread_replies_count": 0,
            "budget_progress": 0.14000000000000001,
            "clocked_in_user_ids": []
        },
        "22097": {
            "id": 22097,
            "jobcode_id": 1779729,
            "parent_jobcode_id": 0,
            "name": "pagination 2",
            "status": "in_progress",
            "description": "",
            "start_date": "",
            "due_date": "",
            "completed_date": "",
            "active": 1,
            "last_modified": "2020-05-27T23:02:06+00:00",
            "created": "2020-05-27T23:02:06+00:00",
            "estimate_id": 0,
            "estimate_by": null,
            "estimate_by__id": 0,
            "total_clocked_in_seconds": 0,
            "total_clocked_out_seconds": 0,
            "total_tracked_seconds": 0,
            "total_estimated_seconds": 0,
            "total_note_count": 0,
            "unread_posts_count": 0,
            "unread_replies_count": 0,
            "budget_progress": null,
            "clocked_in_user_ids": []
        }
    }
}

Retrieves a project estimate report, with filters to narrow down the results.

The project estimate report combines information about each project and time tracked against it.

HTTP Request

posthttps://rest.tsheets.com/api/v1/reports/project_estimate

Filter Properties

Pass an an object of filters as the value to a 'data' property (see example).

project_ids
optional
Int Array Array of one or more project ids. Only time for these projects will be included.
parent_jobcode_id
optional
Int A jobcode id. Only time for projects under this jobcode will be included.
jobcode_ids
optional
Int Array Array of one or more jobcode ids. Only time for projects associated with these jobcodes will be included.
statuses
optional
String Array Array of one or more project statuses. 'in_progress', 'complete'.
page
optional
Int A page number. Default is 1.
per_page
optional
Int Deprecated. Use limit for new code.
Represents how many results you'd like to retrieve per request. Default is 50. Max is 50.
If a value over 50 is provided, it is ignored, and the max is used.
limit
optional
Int Represents how many results you'd like to retrieve per request. Default is 200. Max is 200.
If present, this value must be: an integer, greater than zero, and not greater than 200.
Setting limit less than 1 or greater than 200 will result in an error.
active
optional
String 'yes', 'no', or 'both'. Default is 'yes'.
supplemental_data
optional
String 'yes' or 'no'. Default is 'yes'. Indicates whether supplemental data should be returned.
results_as_array
optional
String 'yes' or 'no'. Default is 'no'. Indicates whether results should be returned as an array instead of an object.
sort_by
optional
String Multi-field sorting. Comma seperated list of fields to sort on. Default is '+name'. Sorting begins with left-most field and continues to the right. Requires directional operator ('-' = 'descending', '+' = 'ascending') in front of each field name. Sorting occurs before any pagination is applied. Setting anything in sort_by will force results_as_array = 'yes', in order to preserve ordering in the payload response. As such, results will now be an array instead of an object. Current allowed fields to sort on are: 'name', 'due_date', 'budget_progress', 'total_note_count', 'unread_posts_count'.
search
optional
JSON Object An object with a key/value map of properties and search terms. List of allowed keys:
  • name: String * will be interpreted as a wild card. Starts matching from the beginning of the string.
has_time_tracked
optional
String 'yes' or 'no'. Default is 'no'. Indicates whether to filter results on time tracked dates.
time_tracked_start_date
optional
String YYYY-MM-DD formatted date. Any time with a time tracked falling on or after this date will be included.
time_tracked_end_date
optional
String YYYY-MM-DD formatted date. Any time with a time tracked falling on or before this date will be included.

Understanding the Output

See explanation of response layout to the right.

Retrieve Project Estimate Detail Reports

Response Layout

{
  "projects": {
    "279": {
        "id": 279,
        "jobcode_id": 48979,
        "parent_jobcode_id": 48959,
        "name": "Installing tires",
        "status": "in_progress",
        "description": "All four wheels and tires need to be installed, aligned. ",
        "start_date": "2020-03-03",
        "due_date": "2020-03-06",
        "completed_date": "",
        "active": 1,
        "last_modified": "2020-03-02T17:19:12+00:00",
        "created": "2020-03-02T17:19:12+00:00",
        "estimate_id": 5,
        "estimate_by": "none",
        "estimate_by__id": 0,
        "total_clocked_in_seconds": 0,
        "total_clocked_out_seconds": 12327,
        "total_tracked_seconds": 12327, ## The total time for the project.
        "total_estimated_seconds": 90000,
        "total_note_count": 0,
        "unread_posts_count": 0,
        "budget_progress": 0.14000000000000001,
        "clocked_in_user_ids": [],
        "tracked_time": {   ## The time recorded for the project broken down by users, groups, jobcodes, customfields, and customfield items.
            "users": {
                "3681": {
                    "total_clocked_in_seconds": 0,       ## The time recorded for the project from employees still on the clock. 
                    "total_clocked_out_seconds": 12327,  ## The time recorded for the project from employees with completed timesheets. 
                    "total_tracked_seconds": 12327,
                    "on_the_clock": false
                }
            },
            "groups": {
                "0": {
                    "users": {
                        "3681": {
                            "total_clocked_in_seconds": 0,
                            "total_clocked_out_seconds": 12327,
                            "total_tracked_seconds": 12327,
                            "on_the_clock": false
                        }
                    }
                }
            },
            "jobcodes": {
                "48979": {
                    "total_clocked_in_seconds": 0,
                    "total_clocked_out_seconds": 12327,
                    "total_tracked_seconds": 12327,
                    "on_the_clock": false,
                    "users": {
                        "3681": {
                            "total_clocked_in_seconds": 0,
                            "total_clocked_out_seconds": 12327,
                            "total_tracked_seconds": 12327,
                            "on_the_clock": false
                        }
                    }
                }
            },
            "customfields": []
        },
        "estimate_items": [],  ## Any estimate items and their tracked time.
        "on_the_clock": false,
        "customfielditem_id": 0,
        "assigned_to_all": true,
        "preview_assigned_user_ids": [],
        "total_assigned_users": 0
    }
  }
}

Example: Generate a project estimate detail report for project id 12345.

Request Body

{
    "data": 
    {
    "project_id": 2557137,
    "supplemental_data": "yes",
    "results_as_array": "no"
    }
}

Request

curl -X POST \
  https://rest.tsheets.com/api/v1/reports/project_estimate_detail \
  -H 'Authorization: Bearer <TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '<REQUEST BODY>'
var client = new RestClient("https://rest.tsheets.com/api/v1/reports/project_estimate_detail");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <TOKEN>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "<REQUEST BODY>", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/reports/project_estimate_detail")
Dim request = New RestRequest(Method.POST)
request.AddHeader("Authorization", "Bearer <TOKEN>")
request.AddHeader("Content-Type", "application/json")
request.AddParameter("application/json", "<REQUEST BODY>", ParameterType.RequestBody);
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<REQUEST BODY>");
Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/reports/project_estimate_detail")
  .post(body)
  .addHeader("Authorization", "Bearer <TOKEN>")
  .addHeader("Content-Type", "application/json")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/reminders?user_ids=0,37&reminder_types=clock-in&modified_since=2018-07-15T19:32:00-06:00",
  "method": "POST",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
    "Content-Type", "application/json",
  },
  "processData": false,
  "data": "<REQUEST BODY>"
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'POST',
  url: 'https://rest.tsheets.com/api/v1/reports/project_estimate_detail',
  headers: 
  { 
     'Authorization': 'Bearer <TOKEN>',
     'Content-Type': 'application/json',
  },
  body: '<REQUEST BODY>',
  json: true };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/reports/project_estimate_detail');
$request->setMethod(HTTP_METH_POST);

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
  'Content-Type' => 'application/json',
));

$request->setBody('<REQUEST BODY>');

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/reports/project_estimate_detail")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <TOKEN>',
request["Content-Type"] = 'application/json',
request.body = "<REQUEST BODY>"

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/reports/project_estimate_detail"

payload = "<REQUEST BODY>"
headers = {
    'Authorization': 'Bearer <TOKEN>',
    'Content-Type': 'application/json',
    }

response = requests.request("POST", url, data=payload, headers=headers)

print(response.text)
package main

import (
  "fmt"
  "strings"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/reports/project_estimate_detail"

  payload := strings.NewReader("<REQUEST BODY>")

  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, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))

}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
   "Content-Type": "application/json",
]
let parameters = <REQUEST BODY> as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/reports/project_estimate_detail")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest,
  completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');
$client->addHeader('Content-Type', 'application/json');

$req = '<REQUEST BODY>';

$url="https://rest.tsheets.com/api/v1/reports/project_estimate_detail"; 

$client->POST($url, $req);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
    "filters": {
        "project_id": 279
    },
    "projects": {
        "279": {
            "id": 279,
            "jobcode_id": 48979,
            "parent_jobcode_id": 48959,
            "name": "Installing tires",
            "status": "in_progress",
            "description": "All four wheels and tires need to be installed, aligned. ",
            "start_date": "2020-03-03",
            "due_date": "2020-03-06",
            "completed_date": "",
            "active": 1,
            "last_modified": "2020-03-02T17:19:12+00:00",
            "created": "2020-03-02T17:19:12+00:00",
            "estimate_id": 5,
            "estimate_by": "none",
            "estimate_by__id": 0,
            "total_clocked_in_seconds": 0,
            "total_clocked_out_seconds": 12327,
            "total_tracked_seconds": 12327,
            "total_estimated_seconds": 90000,
            "total_note_count": 0,
            "unread_posts_count": 0,
            "budget_progress": 0.14000000000000001,
            "clocked_in_user_ids": [],
            "tracked_time": {
                "users": {
                    "3681": {
                        "total_clocked_in_seconds": 0,
                        "total_clocked_out_seconds": 12327,
                        "total_tracked_seconds": 12327,
                        "on_the_clock": false
                    }
                },
                "groups": {
                    "0": {
                        "users": {
                            "3681": {
                                "total_clocked_in_seconds": 0,
                                "total_clocked_out_seconds": 12327,
                                "total_tracked_seconds": 12327,
                                "on_the_clock": false
                            }
                        }
                    }
                },
                "jobcodes": {
                    "48979": {
                        "total_clocked_in_seconds": 0,
                        "total_clocked_out_seconds": 12327,
                        "total_tracked_seconds": 12327,
                        "on_the_clock": false,
                        "users": {
                            "3681": {
                                "total_clocked_in_seconds": 0,
                                "total_clocked_out_seconds": 12327,
                                "total_tracked_seconds": 12327,
                                "on_the_clock": false
                            }
                        }
                    }
                },
                "customfields": []
            },
            "estimate_items": [],
            "on_the_clock": false,
            "customfielditem_id": 0,
            "assigned_to_all": true,
            "preview_assigned_user_ids": [],
            "total_assigned_users": 0
        }
    },
    "supplemental_data": {
       ...
    }
}

Retrieves a project estimate detail report, with filters to narrow down the results.

The project estimate detail report is similar to the project estimate report but offers a detailed breakdown of time for each user, group, jobcode, and customfield item. This report can only be ran for a single project at a time by specifying a project_id filter.

HTTP Request

posthttps://rest.tsheets.com/api/v1/reports/project_estimate_detail

Filter Properties

Pass an an object of filters as the value to a 'data' property (see example).

project_id
required
Int A of project id. Only time for this project will be included.
supplemental_data
optional
String 'yes' or 'no'. Default is 'yes'. Indicates whether supplemental data should be returned.
results_as_array
optional
String 'yes' or 'no'. Default is 'no'. Indicates whether results should be returned as an array instead of an object.

Understanding the Output

See explanation of response layout to the right.

Retrieve Project Report

Response Layout

{
  "results": {
    "project_report": {
      "start_date": "2019-03-02",
      "end_date": "2019-03-15",
      "totals": {
        "users": {                 # This contains all users, indexed by user_id and
          "29604": "0.08"          #   the number of hours for each.
        },
        "groups": {                # This contains the number of hours for each group.
          "0": 0.08                # Time for which there is no group
        },                         #   is represented by an index of '0'.
        "jobcodes": {              # This contains the number of hours for each jobcode.
          "4647114": "0.08"        # Time for which there is no jobcode
        },                         #   is represented by an index of '0'.
        "customfields": {          # This contains the number of hours for each customfield.
          "28840": {               # Indexes are each customfield id.
            "0": "0.08"            # Each of these sub-containers is a breakdown of the
                                   #   amount of hours for each item (indexed by id) in
                                   #   the customfield. Time for which there is no item
                                   #   assigned from this customfield is represented by
          },                       #   a customfielditem id of '0'.
          "2054": {
            "0": "0.08"
          },
          "64": {
            "664014": "0.08"
          },
          "34": {
            "0": "0.08"
          },
          "54": {
            "0": "0.08"
          },
          "44": {
            "3711483": "0.08"
          },
          "3184": {
            "0": "0.08"
          }
        }
      }
    }
  }
}

Example: Retrieve a project report for time recorded within an account.

Request Body

{
 "data":
  {
    "start_date": "2018-03-02",
    "end_date": "2018-03-15",
    "customfielditems": {
      "44": [
        "jeidh",
        "Customer2"
      ]
    },
    "jobcode_ids": [
      "4647114",
      "128934",
      "120981"
    ]
  }
}

Request

curl -X POST \
  https://rest.tsheets.com/api/v1/reports/project \
  -H 'Authorization: Bearer <TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '<REQUEST BODY>'
var client = new RestClient("https://rest.tsheets.com/api/v1/reports/project");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <TOKEN>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "<REQUEST BODY>", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/reports/project")
Dim request = New RestRequest(Method.POST)
request.AddHeader("Authorization", "Bearer <TOKEN>")
request.AddHeader("Content-Type", "application/json")
request.AddParameter("application/json", "<REQUEST BODY>", ParameterType.RequestBody);
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<REQUEST BODY>");
Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/reports/project")
  .post(body)
  .addHeader("Authorization", "Bearer <TOKEN>")
  .addHeader("Content-Type", "application/json")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/reminders?user_ids=0,37&reminder_types=clock-in&modified_since=2018-07-15T19:32:00-06:00",
  "method": "POST",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
    "Content-Type", "application/json",
  },
  "processData": false,
  "data": "<REQUEST BODY>"
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'POST',
  url: 'https://rest.tsheets.com/api/v1/reports/project',
  headers: 
  { 
     'Authorization': 'Bearer <TOKEN>',
     'Content-Type': 'application/json',
  },
  body: '<REQUEST BODY>',
  json: true };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/reports/project');
$request->setMethod(HTTP_METH_POST);

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
  'Content-Type' => 'application/json',
));

$request->setBody('<REQUEST BODY>');

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/reports/project")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <TOKEN>',
request["Content-Type"] = 'application/json',
request.body = "<REQUEST BODY>"

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/reports/project"

payload = "<REQUEST BODY>"
headers = {
    'Authorization': 'Bearer <TOKEN>',
    'Content-Type': 'application/json',
    }

response = requests.request("POST", url, data=payload, headers=headers)

print(response.text)
package main

import (
  "fmt"
  "strings"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/reports/project"

  payload := strings.NewReader("<REQUEST BODY>")

  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, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))

}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
   "Content-Type": "application/json",
]
let parameters = <REQUEST BODY> as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/reports/project")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest,
  completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');
$client->addHeader('Content-Type', 'application/json');

$req = '<REQUEST BODY>';

$url="https://rest.tsheets.com/api/v1/reports/project"; 

$client->POST($url, $req);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "filters": {
      "user_ids": [],
      "group_ids": [],
      "jobcode_type": "both",
      "customfielditems": {
        "44": [
          "jeidh",
          "Customer2"
        ]
      },
      "jobcode_ids": [
        "4647114",
        "128934",
        "120981"
      ]
    },
    "project_report": {
      "start_date": "2018-03-02",
      "end_date": "2018-03-15",
      "totals": {
        "users": {
          "29604": "0.08"
        },
        "groups": {
          "0": 0.08
        },
        "jobcodes": {
          "4647114": "0.08"
        },
        "customfields": {
          "28840": {
            "0": "0.08"
          },
          "2054": {
            "0": "0.08"
          },
          "64": {
            "664014": "0.08"
          },
          "34": {
            "0": "0.08"
          },
          "54": {
            "0": "0.08"
          },
          "44": {
            "3711483": "0.08"
          },
          "3184": {
            "0": "0.08"
          }
        }
      }
    }
  },
  "supplemental_data": {
    "users": {
      "29604": {
        "id": 29604,
        "first_name": "Rand",
        "last_name": "test15",
        "group_id": 0,
        "active": true,
        ...
      }
    },
    "jobcodes": {
      "4647114": {
        "id": 4647114,
        "parent_id": 235494,
        "assigned_to_all": true,
        "billable": false,
        "active": false,
        "type": "regular",
        ...
      }
    },
    "customfields": {
      "28840": {
        "id": 28840,
        "required": true,
        "applies_to": "timesheet",
        "type": "managed-list",
        ...
      }
    },
    "customfielditems": {
      "664014": {
        "id": 664014,
        "customfield_id": 64,
        "active": true,
        ...
      },
      "3711483": {
        "id": 3711483,
        "customfield_id": 44,
        "active": true,
        ...
      }
    }
  }
}

Retrieves a project report, with filters to narrow down the results.

HTTP Request

posthttps://rest.tsheets.com/api/v1/reports/project

Filter Properties

Pass an an object of filters as the value to a 'data' property (see example).

start_date
required
String YYYY-MM-DD formatted date. Any time with a date falling on or after this date will be included.
end_date
required
String YYYY-MM-DD formatted date. Any time with a date falling on or before this date will be included.
user_ids
optional
Int A comma-separated list of user ids. Only time for these users will be included.
group_ids
optional
Int A comma-seperated list of group ids. Only time for users from these groups will be included.
jobcode_ids
optional
Int A comma-seperated list of jobcode ids. Only time for these jobcodes will be included.
jobcode_type
optional
String The type of jobcodes to include. 'regular', 'pto', 'unpaid_break', 'paid_break', or 'all'. Default is 'all'
customfielditems
optional
JSON Object An object with customfield_id as the properties, and each value being an array of customfielditem values. i.e.

"customfielditems": {
  "12437": [
    "ProjectX",
    "Wolverine"
  ]
}

Understanding the Output

See explanation of response layout to the right.

Schedule Calendars

The Schedule Calendar Object

Example

{
  "id": 72595,
  "name": "Schedule Calendar Name",
  "last_modified": "2018-07-15T19:33:57+00:00",
  "created": "2018-07-15T19:08:33+00:00"
}

Following is a list of the properties that belong to a schedule calendar object, and a description of each.

id
read-only
Int Id of the schedule calendar.
name
read-write
String The name of the schedule calendar.
last_modified
read-only
String Date/time when this schedule calendar was last modified, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm)
created
read-only
String Date/time when this schedule calendar was created, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm)

Retrieve Schedule Calendars

Example: Retrieve a list of all schedule calendars.

Request

curl "https://rest.tsheets.com/api/v1/schedule_calendars" \
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/schedule_calendars");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/schedule_calendars")
Dim request = New RestRequest(Method.[GET])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/schedule_calendars")
  .get()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/schedule_calendars",
  "method": "GET",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'GET',
  url: 'https://rest.tsheets.com/api/v1/schedule_calendars',
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/schedule_calendars');
$request->setMethod(HTTP_METH_GET);

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/schedule_calendars")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/schedule_calendars"

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/schedule_calendars"

  req, _ := http.NewRequest("GET", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/schedule_calendars")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest, completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/schedule_calendars"; 

$client->GET($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "schedule_calendars": {
      "72595": {
        "id": 72595,
        "name": "Schedule Calendar Name",
        "last_modified": "2018-07-15T19:31:57+00:00",
        "created": "2018-07-15T19:08:33+00:00"
      },
      "72597": {
        "id": 72597,
        "name": "Schedule Calendar Name2",
        "last_modified": "2018-07-15T19:33:57+00:00",
        "created": "2018-07-15T19:08:33+00:00"
      }
    }
  }
}

Example: Retrieve schedule calendars that have been modified since a given date and time.

Request

curl "https://rest.tsheets.com/api/v1/schedule_calendars?modified_since=2018-07-15T19:32:00-06:00" \
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/schedule_calendars?modified_since=2018-07-15T19:32:00-06:00");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/schedule_calendars?modified_since=2018-07-15T19:32:00-06:00")
Dim request = New RestRequest(Method.[GET])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/schedule_calendars?modified_since=2018-07-15T19:32:00-06:00")
  .get()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/schedule_calendars?modified_since=2018-07-15T19:32:00-06:00",
  "method": "GET",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'GET',
  url: 'https://rest.tsheets.com/api/v1/schedule_calendars',
  qs: {
    modified_since: '2018-07-15T19:32:00-06:00',
  },
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/schedule_calendars');
$request->setMethod(HTTP_METH_GET);

$request->setQueryData(array(
  'modified_since' => '2018-07-15T19:32:00-06:00',
));

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/schedule_calendars?modified_since=2018-07-15T19:32:00-06:00")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/schedule_calendars"

querystring = {
  "modified_since":"2018-07-15T19:32:00-06:00",
}

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/schedule_calendars?modified_since=2018-07-15T19:32:00-06:00"

  req, _ := http.NewRequest("GET", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/schedule_calendars?modified_since=2018-07-15T19:32:00-06:00")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest, completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/schedule_calendars?modified_since=2018-07-15T19:32:00-06:00"; 

$client->GET($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "schedule_calendars": {
      "72595": {
        "id": 72595,
        "name": "Schedule Calendar Name",
        "last_modified": "2018-07-15T19:33:57+00:00",
        "created": "2018-07-15T19:08:33+00:00"
      }
    }
  }
}

Retrieves a list of schedule calendars associated with your employees, with filters to narrow down the results.

HTTP Request

gethttps://rest.tsheets.com/api/v1/schedule_calendars

Filter Parameters

ids
optional
Int Comma separated list of one or more schedule calendar ids you'd like to filter on. Only schedule calendars with an id set to one of these values will be returned.
modified_before
optional
String Only schedule calendars modified before this date/time will be returned, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm).
modified_since
optional
String Only schedule calendars modified since this date/time will be returned, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm).
supplemental_data
optional
String 'yes' or 'no'. Default is 'yes'. Indicates whether supplemental data should be returned.
per_page
optional
Int Deprecated. Use limit for new code.
Represents how many results you'd like to retrieve per request. Default is 50. Max is 50.
If a value over 50 is provided, it is ignored, and the max is used.
limit
optional
Int Represents how many results you'd like to retrieve per request. Default is 200. Max is 200.
If present, this value must be: an integer, greater than zero, and not greater than 200.
Setting limit less than 1 or greater than 200 will result in an error.
page
optional
Int Represents the page of results you'd like to retrieve. Default is 1.

Schedule Events

The Schedule Event Object

Example

{
  "id": 894562,
  "user_id": 1283037,
  "unassigned": false,
  "schedule_calendar_id": 72595,
  "jobcode_id": 17285791,
  "start": "2018-08-08T08:00:00-06:00",
  "end": "2018-08-08T14:00:00-06:00",
  "timezone": "tsMT",
  "notes": "Some Custom Notes",
  "all_day": false,
  "assigned_user_ids": [
    "332234"
  ],
  "active": true,
  "draft": false,
  "title": "Shift work",
  "location": "235 E Colchester Dr 101, Eagle, ID 83616",
  "color": "#BF1959",
  "last_modified": "2018-08-09T17:30:54-06:00",
  "created": "2018-07-15T19:08:33-06:00",
  "customfields": {
    "19142": "Item 1",
    "19144": "Item 2"
  }
}
id
read-only
Int Id of the event.
schedule_calendar_id
read-write
Int Id of the calendar that contains this event.
start
read-write
String Date/time that represents the start time of this schedule event, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm)
end
read-write
String Date/time that represents the end time of this schedule event, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm)
all_day
read-write
Boolean If true, the event duration is all day on the day specified in start. If false, the event duration is determined by date/time specified in end.
user_id
read-only
Int Id of the user that this event belongs to.
unassigned
read-only
Boolean If true, this event is unassigned. If false, the event is assigned to the user specified in user_id.
assigned_user_ids
read-write
Array Ids of the user(s) assigned to this event. Empty array if the event is unassigned. Changing the assigned user IDs of an event may result in multiple event modifications. Check for a 201 status code and the supplemental data portion of the response for additional event modifications.
jobcode_id
read-write
Int Id of the jobcode associated with this event.
active
read-write
Boolean If true, the event is active. If false, the event has been deleted/archived.
draft
read-write
Boolean If true, the event is a draft. If false, the event is published. Saving a published event will send the appropriate event published notifications to the assigned users.
timezone
read-write
String Timezone of the schedule event. (i.e. America/Denver)
title
read-write
String Title or name of this event.
notes
read-write
String Notes associated with the event.
location
read-write
String Location of the event. Location can be an address, business name, GPS coordinate, etc., so when users click on the location it will open it up in their mapping application.
color
read-write
String Hex color code assigned to this schedule event. See the table below for a list of valid hex color codes.
customfields
read-write
JSON Object Only present if the Advanced Tracking Add-on is installed. This is a key / value map of customfield ids to the customfield items that are associated with the event.
last_modified
read-only
String Date/time when this schedule event was last modified, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm)
created
read-only
String Date/time when this schedule event was created, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm)

Valid Schedule Event Colors

Light Red
#FAB3AE
Red
#F44336
Light Orange
#F8C499
Beet
#BF1959
Pink
#E91E63
Crimson
#8A2731
Grey
#888888
Light Green
#B3D9B5
Green
#43A047
Teal
#009688
Slate
#486B7A
Blue Grey
#78909C
Light Blue
#A6D5FA
Blue
#2196F3
Indigo
#3F51B5
Deep Purple
#673AB7
Light Purple
#D7A8DF
Purple
#9C27B0
Black
#010101
Brown
#785548
Orange
#EF6C00
Light Olive
#CDC8A2
Olive
#827717
Bloomy Plum
#6A5E72

Retrieve Schedule Events

Example: Retrieve schedule events from a calendar.

Request

curl "https://rest.tsheets.com/api/v1/schedule_events?schedule_calendar_ids=72595&modified_since=2018-01-01T13:00:00-06:00" \
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/schedule_events?schedule_calendar_ids=72595&modified_since=2018-01-01T13:00:00-06:00");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/schedule_events?schedule_calendar_ids=72595&modified_since=2018-01-01T13:00:00-06:00")
Dim request = New RestRequest(Method.[GET])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/schedule_events?schedule_calendar_ids=72595&modified_since=2018-01-01T13:00:00-06:00")
  .get()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/schedule_events?schedule_calendar_ids=72595&modified_since=2018-01-01T13:00:00-06:00",
  "method": "GET",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'GET',
  url: 'https://rest.tsheets.com/api/v1/schedule_events',
  qs: {
    schedule_calendar_ids: '72595',
    modified_since: '2018-01-01T13:00:00-06:00',
  },
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/schedule_events');
$request->setMethod(HTTP_METH_GET);

$request->setQueryData(array(
  'schedule_calendar_ids' => '72595',
  'modified_since' => '2018-01-01T13:00:00-06:00',
));

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/schedule_events?schedule_calendar_ids=72595&modified_since=2018-01-01T13:00:00-06:00")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/schedule_events"

querystring = {
  "schedule_calendar_ids":"72595",
  "modified_since":"2018-01-01T13:00:00-06:00",
}

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/schedule_events?schedule_calendar_ids=72595&modified_since=2018-01-01T13:00:00-06:00"

  req, _ := http.NewRequest("GET", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/schedule_events?schedule_calendar_ids=72595&modified_since=2018-01-01T13:00:00-06:00")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest, completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/schedule_events?schedule_calendar_ids=72595&modified_since=2018-01-01T13:00:00-06:00"; 

$client->GET($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "schedule_events": {
      "894562": {
        "id": 894562,
        "user_id": 1283037,
        "unassigned": false,
        "schedule_calendar_id": 72595,
        "jobcode_id": 17285791,
        "start": "2018-08-08T08:00:00-06:00",
        "end": "2018-08-08T14:00:00-06:00",
        "timezone": "tsMT",
        "notes": "Some Custom Notes",
        "last_modified": "2018-08-09T17:30:54-06:00",
        "created": "2018-07-15T19:08:33-06:00",
        "customfields": {
          "19142": "Item 1",
          "19144": "Item 2"
        }
      },
      "894588": {
        "id": 894588,
        "user_id": 1283037,
        "unassigned": true,
        "schedule_calendar_id": 72595,
        "jobcode_id": 17285791,
        "start": "2018-08-09T08:00:00-06:00",
        "end": "2018-08-09T14:00:00-06:00",
        "timezone": "tsMT",
        "notes": "Some More Custom Notes",
        "last_modified": "2018-08-09T17:31:23-06:00",
        "created": "2018-07-15T19:08:34-06:00"
      }
    },
    "more": false,
    "supplemental_data": {
      "jobcodes": {
        "17285791": {
          "id": 17285791,
          "parent_id": 0,
          "assigned_to_all": false,
          "billable": false,
          "active": true,
          "type": "regular",
          ...
        }
      },
      "users": {
        "1283037": {
          "id": 1283037,
          "first_name": "Alexander",
          "last_name": "Luzzana",
          "group_id": 144959,
          "active": true,
          ...
        },
        "customfields": {
          "19142": {
            "id": 19142,
            "required": false,
            "type": "timesheet",
            ...
          },
          "19144": {
            "id": 19144,
            "required": false,
            "type": "timesheet",
            ...
          }
        }
      }
    }
  }
}

Retrieves a list of schedule events associated with your employees, with filters to narrow down the results.

HTTP Request

gethttps://rest.tsheets.com/api/v1/schedule_events

Filter Parameters

ids
required (unless modified_before, modified_since, or start are set)
Int Comma separated list of one or more schedule event ids you'd like to filter on. Only schedule events with an id set to one of these values will be returned.
users_ids
optional
Int Comma-separated list of one or more user ids to retrieve schedule events for.
schedule_calendar_ids
required
Int Comma separated list of one or more schedule calendar ids you'd like to filter on. Only schedule events with a schedule calendar id set to one of these values will be returned.
jobcode_ids
optional
Int A comma-separated string of jobcode ids. Only schedule events with these jobcodes will be returned.
start
required (unless ids, modified_before, or modified_since are set)
String Only schedule events starting on or after this date/time will be returned, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm).
end
optional
String Only schedule events ending on or before this date/time will be returned, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm).
active
optional
String 'yes', 'no' or 'both'. Default is 'both'. Only schedule events whose active state match the requested filter will be returned.
active_users
optional
Int '0', '-1' or '1' . Default is '1'. Only schedule events whose users are active will be returned by default. 0 will return events for inactive users. -1 will return events for active and inactive users.
draft
optional
String 'yes', 'no' or 'both'. Default is 'no'. Only schedule events whose draft state match the requested filter will be returned.
team_events
optional
String 'base' or 'instance'. Default is 'instance'. If 'instance' is specified, events that are assigned to multiple users will be returned as individual single events for each assigned user. If 'base' is specified, events that are assigned to multiple users will be returned as one combined event for all assignees.
modified_before
required (unless ids, modified_since, or start are set)
String Only schedule events modified before this date/time will be returned, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm).
modified_since
required (unless ids, modified_before, or start are set)
String Only schedule events modified since this date/time will be returned, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm).
supplemental_data
optional
String 'yes' or 'no'. Default is 'yes'. Indicates whether supplemental data should be returned.
per_page
optional
Int Deprecated. Use limit for new code.
Represents how many results you'd like to retrieve per request. Default is 50. Max is 50.
If a value over 50 is provided, it is ignored, and the max is used.
limit
optional
Int Represents how many results you'd like to retrieve per request. Default is 200. Max is 200.
If present, this value must be: an integer, greater than zero, and not greater than 200.
Setting limit less than 1 or greater than 200 will result in an error.
page
optional
Int Represents the page of results you'd like to retrieve. Default is 1.

Create Schedule Events

Example: Create two new events: one unassigned, and the second assigned to two users.

Request Body

{
  "data": [{
    "schedule_calendar_id": 5,
    "start": "2018-12-05T16:00:00+00:00",
    "end": "2018-12-05T18:00:00+00:00",
    "assigned_user_ids": "",
    "title": "unassigned event",
    "draft": true,
    "active": true
  }, {
    "schedule_calendar_id": 5,
    "start": "2018-12-05T16:00:00+00:00",
    "end": "2018-12-05T18:00:00+00:00",
    "assigned_user_ids": [11, 1365],
    "title": "assigned to multiple",
    "draft": true,
    "active": true
  }],
  "team_events": "base"
}

Request

curl -X POST \
  https://rest.tsheets.com/api/v1/schedule_events \
  -H 'Authorization: Bearer <TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '<REQUEST BODY>'
var client = new RestClient("https://rest.tsheets.com/api/v1/schedule_events");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <TOKEN>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "<REQUEST BODY>", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/schedule_events")
Dim request = New RestRequest(Method.POST)
request.AddHeader("Authorization", "Bearer <TOKEN>")
request.AddHeader("Content-Type", "application/json")
request.AddParameter("application/json", "<REQUEST BODY>", ParameterType.RequestBody);
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<REQUEST BODY>");
Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/schedule_events")
  .post(body)
  .addHeader("Authorization", "Bearer <TOKEN>")
  .addHeader("Content-Type", "application/json")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/schedule_events?schedule_calendar_ids=72595&modified_since=2018-01-01T13:00:00-06:00",
  "method": "POST",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
    "Content-Type", "application/json",
  },
  "processData": false,
  "data": "<REQUEST BODY>"
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'POST',
  url: 'https://rest.tsheets.com/api/v1/schedule_events',
  headers: 
  { 
     'Authorization': 'Bearer <TOKEN>',
     'Content-Type': 'application/json',
  },
  body: '<REQUEST BODY>',
  json: true };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/schedule_events');
$request->setMethod(HTTP_METH_POST);

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
  'Content-Type' => 'application/json',
));

$request->setBody('<REQUEST BODY>');

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/schedule_events")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <TOKEN>',
request["Content-Type"] = 'application/json',
request.body = "<REQUEST BODY>"

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/schedule_events"

payload = "<REQUEST BODY>"
headers = {
    'Authorization': 'Bearer <TOKEN>',
    'Content-Type': 'application/json',
    }

response = requests.request("POST", url, data=payload, headers=headers)

print(response.text)
package main

import (
  "fmt"
  "strings"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/schedule_events"

  payload := strings.NewReader("<REQUEST BODY>")

  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, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))

}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
   "Content-Type": "application/json",
]
let parameters = <REQUEST BODY> as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/schedule_events")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest,
  completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');
$client->addHeader('Content-Type', 'application/json');

$req = '<REQUEST BODY>';

$url="https://rest.tsheets.com/api/v1/schedule_events"; 

$client->POST($url, $req);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "schedule_events": {
      "1": {
        "_status_code": 200,
        "_status_message": "Created",
        "id": 2816373,
        "user_id": 11,
        "unassigned": true,
        "schedule_calendar_id": 5,
        "jobcode_id": 0,
        "all_day": false,
        "start": "2018-12-05T16:00:00+00:00",
        "end": "2018-12-05T18:00:00+00:00",
        "active": true,
        "draft": true,
        "timezone": "UTC",
        "title": "unassigned event",
        "notes": "",
        "color": "#888888",
        "last_modified": "2018-12-07T17:47:37+00:00",
        "created": "2018-12-07T17:47:37+00:00",
        "customfields": "",
        "location": ""
      },
      "2": {
        "_status_code": 200,
        "_status_message": "Created",
        "id": 2816375,
        "user_id": 11,
        "unassigned": false,
        "schedule_calendar_id": 5,
        "jobcode_id": 0,
        "all_day": false,
        "start": "2018-12-05T16:00:00+00:00",
        "end": "2018-12-05T18:00:00+00:00",
        "active": true,
        "draft": true,
        "timezone": "UTC",
        "title": "assigned to multiple",
        "notes": "",
        "color": "#888888",
        "last_modified": "2018-12-07T17:47:37+00:00",
        "created": "2018-12-07T17:47:37+00:00",
        "customfields": "",
        "assigned_user_ids": "11,1365",
        "location": ""
      }
    }
  },
  "supplemental_data": {
    "users": {
      "11": {
        "id": 11,
        "first_name": "Joni",
        "last_name": "Smith",
        "group_id": 0,
        "active": true,
        ...
      }
    }
  },
  "calendars": {
    "5": {
      "id": "5",
      ...
    }
  }
}

Add one or more schedule events.

HTTP Request

posthttps://rest.tsheets.com/api/v1/schedule_events

Properties

Pass an array of schedule event objects as the value to a 'data' property (see example).

schedule_calendar_id
required
Int Id of the Schedule Calendar that contains this event.
start
required
Int Date/time that represents the start time of this event, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm).
end
required
Int Date/time that represents the end time of this event, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm).
all_day
required
Boolean If true, the event duration is all day on the day specified in start. If false, the event duration is determined by date/time specified in end.
team_events
optional
String 'base' or 'instance'. Default is 'instance'. If 'instance' is specified, supplemental events that are created for multiple users will be returned as individual single events for each assigned user. If 'base' is specified, supplemental events that are created for multiple users will be returned as one combined event for all assignees.

For a full list of the properties that may be set on an event, see the Schedule Event object.

Status Codes

Each event that is created will come back with a _status_code and _status_message that will indicate whether the event was created successfully. If there was a problem creating an event, there may also be an additional field, _status_extra, which will contain more details about the failure.

200 OK. Event was created successfully.
201 Fulfilled. Event was created successfully and additional events that were created as a result are included in the supplemental data section of the response.
403 Permission Denied. The requesting user did not have high enough manage schedule permissions to create the event.
417 Expectation Failed. Something was wrong or missing with the properties supplied for this event. See the _status_extra value for more detail.

Update Schedule Events

Example: Edit the title of an event.

Request Body

{
  "data":
  [
    {
      "schedule_calendar_id":5,
      "id": 2816375,
      "title":"changed title"
    }
  ],
  "team_events": "base"
}

Request

curl -X PUT \
  https://rest.tsheets.com/api/v1/schedule_events \
  -H 'Authorization: Bearer <TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '<REQUEST BODY>'
var client = new RestClient("https://rest.tsheets.com/api/v1/schedule_events");
var request = new RestRequest(Method.PUT);
request.AddHeader("Authorization", "Bearer <TOKEN>");
request.AddHeader("Content-Type", "application/json");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/schedule_events")
Dim request = New RestRequest(Method.PUT)
request.AddHeader("Authorization", "Bearer <TOKEN>")
request.AddHeader("Content-Type", "application/json")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<REQUEST BODY>");
Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/schedule_events")
  .put(body)
  .addHeader("Authorization", "Bearer <TOKEN>")
  .addHeader("Content-Type", "application/json")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/schedule_events?schedule_calendar_ids=72595&modified_since=2018-01-01T13:00:00-06:00",
  "method": "PUT",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
    "Content-Type", "application/json",
  },
  "processData": false,
  "data": "<REQUEST BODY>"
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'PUT',
  url: 'https://rest.tsheets.com/api/v1/schedule_events',
  headers: 
  { 
     'Authorization': 'Bearer <TOKEN>',
     'Content-Type': 'application/json',
  },
  body: '<REQUEST BODY>',
  json: true };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/schedule_events');
$request->setMethod(HTTP_METH_PUT);

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
  'Content-Type' => 'application/json',
));

$request->setBody('<REQUEST BODY>');

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/schedule_events")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <TOKEN>',
request["Content-Type"] = 'application/json',
request.body = "<REQUEST BODY>"

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/schedule_events"

payload = "<REQUEST BODY>"
headers = {
    'Authorization': 'Bearer <TOKEN>',
    'Content-Type': 'application/json',
    }

response = requests.request("PUT", url, data=payload, headers=headers)

print(response.text)
package main

import (
  "fmt"
  "strings"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/schedule_events"

  payload := strings.NewReader("<REQUEST BODY>")

  req, _ := http.NewRequest("PUT", 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, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))

}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
   "Content-Type": "application/json",
]
let parameters = <REQUEST BODY> as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(
  url: NSURL(string: "http://rest.tsheets.com/api/v1/schedule_events")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "PUT"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest,
  completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');
$client->addHeader('Content-Type', 'application/json');

$req = '<REQUEST BODY>';

$url="http://rest.tsheets.com/api/v1/schedule_events"; 

$client->PUT($url, $req);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "schedule_events": {
      "1": {
        "_status_code": 200,
        "_status_message": "Updated",
        "id": 2816375,
        "user_id": 11,
        "unassigned": false,
        "schedule_calendar_id": 5,
        "jobcode_id": 0,
        "all_day": false,
        "start": "2018-12-05T16:00:00+00:00",
        "end": "2018-12-05T18:00:00+00:00",
        "active": true,
        "draft": true,
        "timezone": "UTC",
        "title": "changed title",
        "notes": "",
        "color": "#888888",
        "last_modified": "2018-12-07T18:12:29+00:00",
        "created": "2018-12-07T17:47:37+00:00",
        "customfields": "",
        "assigned_user_ids": "11,1365",
        "location": ""
      }
    }
  },
  "supplemental_data": {
    "users": {
      "11": {
        "id": 11,
        "first_name": "Joni",
        "last_name": "Smith",
        "group_id": 144959,
        "active": true,
        ...
      }
    }
  },
  "calendars": {
    "5": {
      "id": "5",
      ...
    }
  }
}

Edit one or more schedule events.

HTTP Request

puthttps://rest.tsheets.com/api/v1/schedule_events

Properties

Pass an array of schedule event objects as the value to a 'data' property (see example).

id
required
Int Id of the Schedule Calendar Event.
team_events
optional
String 'base' or 'instance'. Default is 'instance'. If 'instance' is specified, supplemental events that are created for multiple users will be returned as individual single events for each assigned user. If 'base' is specified, supplemental events that are created for multiple users will be returned as one combined event for all assignees.

All other properties defined on a schedule event object may be passed in to the request with a new value in order to change it. If the value passed in is the same as it was previously, or if a particular property is not passed in at all, it will be ignored.

Status Codes

Each event that is edited will come back with a _status_code and _status_message that will indicate whether the event was edited successfully. If there was a problem editing the event, there may also be an additional field, _status_extra, which will contain more details about the failure.

200 OK. Event was edited successfully.
201 Fulfilled. Event was edited successfully and additional events that were edited as a result are included in the supplemental data section of the response.
403 Permission Denied. The requesting user did not have high enough manage schedule permissions to edit the event.
417 Expectation Failed. Something was wrong or missing with the properties supplied for this event. See the _status_extra value for more detail.

Timesheets

The Timesheet Object

Example

{
  "id": 135288482,
  "user_id": 1242515,
  "jobcode_id": 17288283,
  "start": "2018-07-16T09:04:00-06:00",
  "end": "2018-07-16T15:57:00-06:00",
  "duration": 24780,
  "date": "2018-07-16",
  "tz": -6,
  "tz_str": "tsMT",
  "type": "regular",
  "location": "(Eagle, ID?)",
  "on_the_clock": false,
  "locked": 0,
  "notes": "",
  "customfields": {
    "19142": "Item 1",
    "19144": "Item 2"
  },
  "attached_files": [
    50692,
    44878
  ],
  "last_modified": "1970-01-01T00:00:00+00:00"
}

Following is a list of the properties that are common to both types of timesheet objects, and a description of each.

id
read-only
Int Id of the timesheet.
user_id
read-write
Int User id for the user that this timesheet belongs to.
jobcode_id
read-write
Int Jobcode id for the jobcode that this timesheet is recorded against.
locked
read-only
Int If greater than 0, the timesheet is locked for editing. A timesheet could be locked for various reasons, such as being exported, invoiced, etc.

Note: The locked setting does not reflect the approved or submitted status of time. To determine whether a timesheet falls within an approved or submitted time frame, check the submitted_to or approved_to properties of the User object that owns the timesheet (you can easily obtain this via the supplemental_data portion of any response dealing with timesheets).
notes
read-write
String Notes associated with this timesheet.
customfields
read-write
JSON Object A key/value map of customfield ids to the customfield items that are associated with the timesheet.

Note: this property is present only if the Custom Fields Add-On is installed.
last_modified
read-only
String Date/time when this timesheet was last modified, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm)
type
read-write
String Either 'regular' or 'manual'. Regular timesheets have a start & end time (duration is calculated by TSheets). Manual timesheets have a date and a duration (in seconds). Unique properties for each timesheet type are below.
on_the_clock
read-only
Boolean If true, the user is currently on the clock (i.e. not clocked out, so end time is empty). If false the user is not currently working on this timesheet. Manual timesheets will always have this property set as false.
attached_files
read-write
Int[] Ids of files attached to this timesheet.
created_by_user_id
read-only
Int User id for the user that initially created this timesheet.

Regular Timesheets

start
read-write
String Date/time that represents the start time of this timesheet, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm)
end
read-write
String Date/time that represents the end time of this timesheet, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm)
date
read-only
String The timesheet's date, in YYYY-MM-DD format.
duration
read-only
Int The total number of seconds recorded for this timesheet.
origin_hint
read-only (except on create)
String A string that will be logged as part of the timesheet history when someone is clocked in, clocked out, or a timesheet is created (with both in/out).

Manual Timesheets

start
read-only
String Not applicable. Will always be an empty string.
end
read-only
String Not applicable. Will always be an empty string.
date
read-write
String The timesheet's date, in YYYY-MM-DD format.
duration
read-write
Int The total number of seconds recorded for this timesheet.

Retrieve Timesheets

Example: Retrieve a list of on_the_clock and not on_the_clock timesheets over a 10-day period.

Request

curl "https://rest.tsheets.com/api/v1/timesheets?start_date=2018-07-15&end_date=2018-07-25&on_the_clock=both" \
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/timesheets?start_date=2018-07-15&end_date=2018-07-25&on_the_clock=both");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/timesheets?start_date=2018-07-15&end_date=2018-07-25&on_the_clock=both")
Dim request = New RestRequest(Method.[GET])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/timesheets?start_date=2018-07-15&end_date=2018-07-25&on_the_clock=both")
  .get()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/timesheets?start_date=2018-07-15&end_date=2018-07-25&on_the_clock=both",
  "method": "GET",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'GET',
  url: 'https://rest.tsheets.com/api/v1/timesheets',
  qs: {
    start_date: '2018-07-15',
    end_date: '2018-07-25',
    on_the_clock: 'both',
  },
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/timesheets');
$request->setMethod(HTTP_METH_GET);

$request->setQueryData(array(
  'start_date' => '2018-07-15',
  'end_date' => '2018-07-25',
  'on_the_clock' => 'both',
));

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/timesheets?start_date=2018-07-15&end_date=2018-07-25&on_the_clock=both")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/timesheets"

querystring = {
  "start_date":"2018-07-15",
  "end_date":"2018-07-25",
  "on_the_clock":"both",
}

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/timesheets?start_date=2018-07-15&end_date=2018-07-25&on_the_clock=both"

  req, _ := http.NewRequest("GET", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/timesheets?start_date=2018-07-15&end_date=2018-07-25&on_the_clock=both")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest, completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/timesheets?start_date=2018-07-15&end_date=2018-07-25&on_the_clock=both"; 

$client->GET($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Example: Retrieve a list of all timesheets within a certain date range which were recorded against a given jobcode id. Set pagination to 10 results/page.

Request

curl "https://rest.tsheets.com/api/v1/timesheets?start_date=2018-01-01&end_date=2018-01-31&on_the_clock=no&jobcode_ids=235494&limit=10" \
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/timesheets?start_date=2018-01-01&end_date=2018-01-31&on_the_clock=no&jobcode_ids=235494&limit=10");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/timesheets?start_date=2018-01-01&end_date=2018-01-31&on_the_clock=no&jobcode_ids=235494&limit=10")
Dim request = New RestRequest(Method.[GET])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/timesheets?start_date=2018-01-01&end_date=2018-01-31&on_the_clock=no&jobcode_ids=235494&limit=10")
  .get()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/timesheets?start_date=2018-01-01&end_date=2018-01-31&on_the_clock=no&jobcode_ids=235494&limit=10",
  "method": "GET",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'GET',
  url: 'https://rest.tsheets.com/api/v1/timesheets',
  qs: {
    start_date: '2018-01-01',
    end_date: '2018-01-31',
    on_the_clock: 'no',
    jobcode_ids: '235494',
    limit: '10',
  },
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/timesheets');
$request->setMethod(HTTP_METH_GET);

$request->setQueryData(array(
  'start_date' => '2018-01-01',
  'end_date' => '2018-01-31',
  'on_the_clock' => 'no',
  'jobcode_ids' => '235494',
  'limit' => '10',
));

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/timesheets?start_date=2018-01-01&end_date=2018-01-31&on_the_clock=no&jobcode_ids=235494&limit=10")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/timesheets"

querystring = {
  "start_date":"2018-01-01",
  "end_date":"2018-01-31",
  "on_the_clock":"no",
  "jobcode_ids":"235494",
  "limit":"10",
}

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/timesheets?start_date=2018-01-01&end_date=2018-01-31&on_the_clock=no&jobcode_ids=235494&limit=10"

  req, _ := http.NewRequest("GET", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/timesheets?start_date=2018-01-01&end_date=2018-01-31&on_the_clock=no&jobcode_ids=235494&limit=10")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest, completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/timesheets?start_date=2018-01-01&end_date=2018-01-31&on_the_clock=no&jobcode_ids=235494&limit=10"; 

$client->GET($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Example: Retrieve a list of timesheets with given ids.

Request

curl "https://rest.tsheets.com/api/v1/timesheets?ids=12,367,348" \
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/timesheets?ids=12,367,348");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/timesheets?ids=12,367,348")
Dim request = New RestRequest(Method.[GET])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/timesheets?ids=12,367,348")
  .get()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/timesheets?ids=12,367,348",
  "method": "GET",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'GET',
  url: 'https://rest.tsheets.com/api/v1/timesheets',
  qs: {
    ids: '12,367,348',
  },
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/timesheets');
$request->setMethod(HTTP_METH_GET);

$request->setQueryData(array(
  'ids' => '12,367,348',
));

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/timesheets?ids=12,367,348")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/timesheets"

querystring = {
  "ids":"12,367,348",
}

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/timesheets?ids=12,367,348"

  req, _ := http.NewRequest("GET", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/timesheets?ids=12,367,348")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest, completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/timesheets?ids=12,367,348"; 

$client->GET($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Example: Retrieve page 3 of a list of timesheets linked to a specific user within a given time range.

Request

curl "https://rest.tsheets.com/api/v1/timesheets?page=3&user_ids=1123&start_date=2018-01-01&end_date=2018-02-01" \
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/timesheets?page=3&user_ids=1123&start_date=2018-01-01&end_date=2018-02-01");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/timesheets?page=3&user_ids=1123&start_date=2018-01-01&end_date=2018-02-01")
Dim request = New RestRequest(Method.[GET])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/timesheets?page=3&user_ids=1123&start_date=2018-01-01&end_date=2018-02-01")
  .get()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/timesheets?page=3&user_ids=1123&start_date=2018-01-01&end_date=2018-02-01",
  "method": "GET",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'GET',
  url: 'https://rest.tsheets.com/api/v1/timesheets',
  qs: {
    page: '3',
    user_ids: '1123',
    start_date: '2018-01-01',
    end_date: '2018-02-01',
  },
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/timesheets');
$request->setMethod(HTTP_METH_GET);

$request->setQueryData(array(
  'page' => '3',
  'user_ids' => '1123',
  'start_date' => '2018-01-01',
  'end_date' => '2018-02-01',
));

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/timesheets?page=3&user_ids=1123&start_date=2018-01-01&end_date=2018-02-01")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/timesheets"

querystring = {
  "page":"3",
  "user_ids":"1123",
  "start_date":"2018-01-01",
  "end_date":"2018-02-01",
}

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/timesheets?page=3&user_ids=1123&start_date=2018-01-01&end_date=2018-02-01"

  req, _ := http.NewRequest("GET", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/timesheets?page=3&user_ids=1123&start_date=2018-01-01&end_date=2018-02-01")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest, completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/timesheets?page=3&user_ids=1123&start_date=2018-01-01&end_date=2018-02-01"; 

$client->GET($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Example: Retrieve a list of timesheets that have been modified since a given date.

Request

curl "https://rest.tsheets.com/api/v1/timesheets?modified_since=2018-01-01T00:00:00-06:00" \
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/timesheets?modified_since=2018-01-01T00:00:00-06:00");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/timesheets?modified_since=2018-01-01T00:00:00-06:00")
Dim request = New RestRequest(Method.[GET])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/timesheets?modified_since=2018-01-01T00:00:00-06:00")
  .get()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/timesheets?modified_since=2018-01-01T00:00:00-06:00",
  "method": "GET",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'GET',
  url: 'https://rest.tsheets.com/api/v1/timesheets',
  qs: {
    modified_since: '2018-01-01T00:00:00-06:00',
  },
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/timesheets');
$request->setMethod(HTTP_METH_GET);

$request->setQueryData(array(
  'modified_since' => '2018-01-01T00:00:00-06:00',
));

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/timesheets?modified_since=2018-01-01T00:00:00-06:00")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/timesheets"

querystring = {
  "modified_since":"2018-01-01T00:00:00-06:00",
}

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/timesheets?modified_since=2018-01-01T00:00:00-06:00"

  req, _ := http.NewRequest("GET", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/timesheets?modified_since=2018-01-01T00:00:00-06:00")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest, completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/timesheets?modified_since=2018-01-01T00:00:00-06:00"; 

$client->GET($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "timesheets": {
      "135288482": {
        "id": 135288482,
        "user_id": 1242515,
        "jobcode_id": 17288283,
        "start": "2018-07-16T09:04:00-06:00",
        "end": "2018-07-16T15:57:00-06:00",
        "duration": 24780,
        "date": "2018-07-16",
        "tz": -6,
        "tz_str": "tsMT",
        "type": "regular",
        "location": "(Eagle, ID?)",
        "on_the_clock": false,
        "locked": 0,
        "notes": "",
        "customfields": {
          "19142": "Item 1",
          "19144": "Item 2"
        },
        "attached_files": [
          50692,
          44878
        ],
        "last_modified": "1970-01-01T00:00:00+00:00"
      },
      "135288514": {
        "id": 135288514,
        "user_id": 1242509,
        "jobcode_id": 18080900,
        "start": "2018-07-16T13:07:00-06:00",
        "end": "2018-07-16T17:29:00-06:00",
        "duration": 15720,
        "date": "2018-07-16",
        "tz": -6,
        "tz_str": "tsMT",
        "type": "regular",
        "location": "(Eagle, ID?)",
        "on_the_clock",
        false,
        "locked": 0,
        "notes": "",
        "customfields": {
          "19142": "Item 1",
          "19144": "Item 2"
        },
        "attached_files": [
          50692,
          44878
        ],
        "last_modified": "1970-01-01T00:00:00+00:00"
      },
      "135288460": {
        "id": 135288460,
        "user_id": 1242509,
        "jobcode_id": 18080900,
        "start": "2018-07-18T08:09:00-06:00",
        "end": "2018-07-18T14:58:00-06:00",
        "duration": 24540,
        "date": "2018-07-18",
        "tz": -6,
        "tz_str": "tsMT",
        "type": "regular",
        "location": "(Eagle, ID?)",
        "on_the_clock",
        false,
        "locked": 0,
        "notes": "",
        "customfields": {
          "19142": "Item 1",
          "19144": "Item 2"
        },
        "attached_files": [
          50692,
          44878
        ],
        "last_modified": "1970-01-01T00:00:00+00:00"
      },
      "135288162": {
        "id": 135288162,
        "user_id": 1242515,
        "jobcode_id": 17288283,
        "start": "2018-07-19T12:06:00-06:00",
        "end": "2018-07-19T14:59:00-06:00",
        "duration": 10380,
        "date": "2018-07-19",
        "tz": -6,
        "tz_str": "tsMT",
        "type": "regular",
        "location": "(Eagle, ID?)",
        "on_the_clock",
        false,
        "locked": 0,
        "notes": "",
        "customfields": {
          "19142": "Item 1",
          "19144": "Item 2"
        },
        "attached_files": [],
        "last_modified": "1970-01-01T00:00:00+00:00"
      },
      "135288102": {
        "id": 135288102,
        "user_id": 1242515,
        "jobcode_id": 17288283,
        "start": "2018-07-22T13:05:00-06:00",
        "end": "2018-07-22T18:07:00-06:00",
        "duration": 18120,
        "date": "2018-07-22",
        "tz": -6,
        "tz_str": "tsMT",
        "type": "regular",
        "location": "(Eagle, ID?)",
        "on_the_clock",
        false,
        "locked": 0,
        "notes": "",
        "customfields": {
          "19142": "Item 1",
          "19144": "Item 2"
        },
        "attached_files": [
          50692,
          44878
        ],
        "last_modified": "1970-01-01T00:00:00+00:00"
      },
      "135522568": {
        "id": 135522568,
        "user_id": 1242515,
        "jobcode_id": 17288283,
        "start": "2018-07-23T08:00:00-06:00",
        "end": "2018-07-23T12:19:12-06:00",
        "duration": 15552,
        "date": "2018-07-23",
        "tz": -6,
        "tz_str": "tsMT",
        "type": "manual",
        "location": "(Eagle, ID?)",
        "on_the_clock",
        false,
        "locked": 0,
        "notes": "This is a test of a manual time entry",
        "customfields": {
          "19142": "Item 1",
          "19144": "Item 2"
        },
        "attached_files": [
          50692,
          44878
        ],
        "last_modified": "1970-01-01T00:00:00+00:00"
      },
      "135366264": {
        "id": 135366264,
        "user_id": 1242515,
        "jobcode_id": 17288283,
        "start": "2018-07-23T08:00:00-06:00",
        "end": "2018-07-23T12:19:12-06:00",
        "duration": 15552,
        "date": "2018-07-23",
        "tz": -6,
        "tz_str": "tsMT",
        "type": "manual",
        "location": "(Eagle, ID?)",
        "on_the_clock",
        false,
        "locked": 0,
        "notes": "This is a test of a manual time entry",
        "customfields": {
          "19142": "Item 1",
          "19144": "Item 2"
        },
        "attached_files": [],
        "last_modified": "1970-01-01T00:00:00+00:00"
      },
      "135288084": {
        "id": 135288084,
        "user_id": 1242509,
        "jobcode_id": 18080900,
        "start": "2018-07-23T09:07:00-06:00",
        "end": "2018-07-23T15:02:00-06:00",
        "duration": 21300,
        "date": "2018-07-23",
        "tz": -6,
        "tz_str": "tsMT",
        "type": "regular",
        "location": "(Eagle, ID?)",
        "on_the_clock",
        false,
        "locked": 0,
        "notes": "",
        "customfields": {
          "19142": "Item 1",
          "19144": "Item 2"
        },
        "attached_files": [
          50692,
          44878
        ],
        "last_modified": "1970-01-01T00:00:00+00:00"
      },
      "135366260": {
        "id": 135366260,
        "user_id": 1242515,
        "jobcode_id": 17288283,
        "start": "2018-07-23T11:00:00-06:00",
        "end": "2018-07-23T14:10:23-06:00",
        "duration": 11423,
        "date": "2018-07-23",
        "tz": -7,
        "tz_str": "tsMT",
        "type": "regular",
        "location": "(Eagle, ID?)",
        "on_the_clock",
        false,
        "locked": 0,
        "notes": "This is a test of the emergency broadcast system",
        "customfields": {
          "19142": "Item 1",
          "19144": "Item 2"
        },
        "attached_files": [],
        "last_modified": "1970-01-01T00:00:00+00:00"
      },
      "135366262": {
        "id": 135366262,
        "user_id": 1242515,
        "jobcode_id": 17288283,
        "start": "2018-07-25T10:30:00-06:00",
        "end": "2018-07-25T14:10:23-06:00",
        "duration": 13223,
        "date": "2018-07-25",
        "tz": -7,
        "tz_str": "tsMT",
        "type": "regular",
        "location": "(Eagle, ID?)",
        "on_the_clock",
        false,
        "locked": 0,
        "notes": "This is a test",
        "customfields": {
          "19142": "Item 1",
          "19144": "Item 2"
        },
        "attached_files": [
          50692,
          44878
        ],
        "last_modified": "1970-01-01T00:00:00+00:00"
      }
    }
  },
  "more": false,
  "supplemental_data": {
    "jobcodes": {
      "17288283": {
        "id": 17288283,
        "parent_id": 0,
        "assigned_to_all": false,
        "billable": false,
        "active": true,
        ...
      },
      "18080900": {
        "id": 18080900,
        "parent_id": 17288279,
        "assigned_to_all": false,
        "billable": false,
        "active": true,
        ...
      },
      "17288279": {
        "id": 17288279,
        "parent_id": 0,
        "assigned_to_all": false,
        "billable": false,
        "active": true,
        ...
      }
    },
    "users": {
      "1242515": {
        "id": 1242515,
        "first_name": "Alexander",
        "last_name": "Luzzana",
        "group_id": 144959,
        "active": true,
        ...
      },
      "1242509": {
        "id": 1242509,
        "first_name": "Courtney",
        "last_name": "Ballenger",
        "group_id": 144961,
        "active": true,
        ...
      }
    },
    "customfields": {
      "19142": {
        "id": 19142,
        "required": false,
        "type": "timesheet",
        ...
      },
      "19144": {
        "id": 19144,
        "required": false,
        "type": "timesheet",
        ...
      }
    },
    "files": {
      "50692": {
        "id": 50692,
        "uploaded_by_user_id": 1242515,
        "file_name": "minion.jpg",
        "active": true,
        ...
      },
      "44878": {
        "id": 44878,
        "uploaded_by_user_id": 1242515,
        "file_name": "minion.jpg",
        "active": true,
        ...
      }
    }
  }
}

Retrieves a list of all timesheets associated with your company, with filters to narrow down the results.

HTTP Request

gethttps://rest.tsheets.com/api/v1/timesheets

Filter Parameters

ids
required (unless modified_before, modified_since, or start_date are set)
Int Comma separated list of one or more timesheet ids you'd like to filter on. Only timesheets with an id set to one of these values will be returned. If omitted, all timesheets matching other specified filters are returned.
start_date
required (unless modified_before, modified_since, or ids is set)
String YYYY-MM-DD formatted date. Any timesheets with a date falling on or after this date will be returned.
end_date
optional
String YYYY-MM-DD formatted date. Any timesheets with a date falling on or before this date will be returned.
jobcode_ids
optional
Int A comma-separated string of jobcode ids. Only time recorded against these jobcodes or one of their children will be returned.
payroll_ids
optional
Int A comma-separated string of payroll ids. Only time recorded against users with these payroll ids will be returned.
user_ids
optional
Int A comma-separated list of user ids. Only timesheets linked to these users will be returned.
group_ids
optional
Int A comma-separated list of group ids. Only timesheets linked to users from these groups will be returned.
on_the_clock
optional
String 'yes', 'no', or 'both'. Default is 'no'. If a timesheet is on_the_clock, it means the user is currently working (has not clocked out yet).
jobcode_type
optional
String 'regular', 'pto', 'paid_break', 'unpaid_break', or 'all'. Default is 'all'. Only timesheets linked to a jobcode of the given type are returned.
modified_before
required (unless modified_since, ids, or start_date are set)
String Only timesheets modified before this date/time will be returned, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm).
modified_since
required (unless modified_before, ids, or start_date are set)
String Only timesheets modified since this date/time will be returned, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm).
supplemental_data
optional
String 'yes' or 'no'. Default is 'yes'. Indicates whether supplemental data should be returned.
per_page
optional
Int Deprecated. Use limit for new code.
Represents how many results you'd like to retrieve per request. Default is 50. Max is 50.
If a value over 50 is provided, it is ignored, and the max is used.
limit
optional
Int Represents how many results you'd like to retrieve per request. Default is 200. Max is 200.
If present, this value must be: an integer, greater than zero, and not greater than 200.
Setting limit less than 1 or greater than 200 will result in an error.
page
optional
Int Represents the page of results you'd like to retrieve. Default is 1.

Create Timesheets

Example: Create three new timesheets (one manual and two regular). Two succeed. The third fails because of an overlap with an existing timesheet.

Request Body

{
 "data":
  [
    {
     "user_id":1242515,
     "type":"regular",
     "start":"2018-07-23T10:00:00-07:00",
     "end":"2018-07-23T13:10:23-07:00",
     "jobcode_id":"17288283",
     "notes":"This is a test of the emergency broadcast system",
     "customfields": {
      "19142":"Item 1",
      "19144":"Item 2"
     },
     "attached_files": [
      50692,
      44878       
     ],
    },
    {
     "user_id":1242515,
     "type":"regular",
     "start":"2018-07-25T09:30:00-07:00",
     "end":"2018-07-25T13:10:23-07:00",
     "jobcode_id":"17288283",
     "notes":"This is a test",
     "customfields": {
      "19142":"Item 1",
      "19144":"Item 2"
     }
     "attached_files": [
      50692,
      44878       
     ],
    },
    {
     "user_id":1242515,
     "type":"manual",
     "date":"2018-07-23",
     "duration":"15552",
     "jobcode_id":"17288283",
     "notes":"This is a test of a manual time entry",
     "customfields": {
      "19142":"Item 1",
      "19144":"Item 2"
     }
    }
  ]
}

Request

curl -X POST \
  https://rest.tsheets.com/api/v1/timesheets \
  -H 'Authorization: Bearer <TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '<REQUEST BODY>'
var client = new RestClient("https://rest.tsheets.com/api/v1/timesheets");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <TOKEN>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "<REQUEST BODY>", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/timesheets")
Dim request = New RestRequest(Method.POST)
request.AddHeader("Authorization", "Bearer <TOKEN>")
request.AddHeader("Content-Type", "application/json")
request.AddParameter("application/json", "<REQUEST BODY>", ParameterType.RequestBody);
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<REQUEST BODY>");
Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/timesheets")
  .post(body)
  .addHeader("Authorization", "Bearer <TOKEN>")
  .addHeader("Content-Type", "application/json")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/timesheets?modified_since=2018-01-01T00:00:00-06:00",
  "method": "POST",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
    "Content-Type", "application/json",
  },
  "processData": false,
  "data": "<REQUEST BODY>"
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'POST',
  url: 'https://rest.tsheets.com/api/v1/timesheets',
  headers: 
  { 
     'Authorization': 'Bearer <TOKEN>',
     'Content-Type': 'application/json',
  },
  body: '<REQUEST BODY>',
  json: true };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/timesheets');
$request->setMethod(HTTP_METH_POST);

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
  'Content-Type' => 'application/json',
));

$request->setBody('<REQUEST BODY>');

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/timesheets")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <TOKEN>',
request["Content-Type"] = 'application/json',
request.body = "<REQUEST BODY>"

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/timesheets"

payload = "<REQUEST BODY>"
headers = {
    'Authorization': 'Bearer <TOKEN>',
    'Content-Type': 'application/json',
    }

response = requests.request("POST", url, data=payload, headers=headers)

print(response.text)
package main

import (
  "fmt"
  "strings"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/timesheets"

  payload := strings.NewReader("<REQUEST BODY>")

  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, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))

}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
   "Content-Type": "application/json",
]
let parameters = <REQUEST BODY> as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/timesheets")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest,
  completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');
$client->addHeader('Content-Type', 'application/json');

$req = '<REQUEST BODY>';

$url="https://rest.tsheets.com/api/v1/timesheets"; 

$client->POST($url, $req);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "timesheets": {
      "1": {
        "_status_code": 200,
        "_status_message": "Created",
        "id": 135653104,
        "user_id": 1242515,
        "jobcode_id": 17288283,
        "start": "2018-07-23T11:00:00-06:00",
        "end": "2018-07-23T14:10:23-06:00",
        "duration": 11423,
        "date": "2018-07-23",
        "tz": -7,
        "tz_str": "tsMT",
        "type": "regular",
        "location": "(Eagle, ID?)",
        "active": "0",
        "locked": 0,
        "notes": "This is a test of the emergency broadcast system",
        "customfields": {
          "19142": "Item 1",
          "19144": "Item 2"
        },
        "attached_files": [
          50692,
          44878
        ],
        "last_modified": "1970-01-01T00:00:00+00:00"
      },
      "2": {
        "_status_code": 200,
        "_status_message": "Created",
        "id": 135653106,
        "user_id": 1242515,
        "jobcode_id": 17288283,
        "start": "2018-07-25T10:30:00-06:00",
        "end": "2018-07-25T14:10:23-06:00",
        "duration": 13223,
        "date": "2018-07-25",
        "tz": -7,
        "tz_str": "tsMT",
        "type": "regular",
        "location": "(Eagle, ID?)",
        "active": "0",
        "locked": 0,
        "notes": "This is a test",
        "customfields": {
          "19142": "Item 1",
          "19144": "Item 2"
        },
        "attached_files": [
          50692,
          44878
        ],
        "last_modified": "1970-01-01T00:00:00+00:00"
      },
      "3": {
        "_status_code": 200,
        "_status_message": "Created",
        "id": 135653108,
        "user_id": 1242515,
        "jobcode_id": 17288283,
        "start": "2018-07-23T08:00:00-06:00",
        "end": "2018-07-23T12:19:12-06:00",
        "duration": 15552,
        "date": "2018-07-23",
        "tz": -6,
        "tz_str": "tsMT",
        "type": "manual",
        "location": "(Eagle, ID?)",
        "active": "0",
        "locked": 0,
        "notes": "This is a test of a manual time entry",
        "customfields": {
          "19142": "Item 1",
          "19144": "Item 2"
        },
        "attached_files": [],
        "last_modified": "1970-01-01T00:00:00+00:00"
      }
    }
  },
  "supplemental_data": {
    "jobcodes": {
      "17288283": {
        "id": 17288283,
        "parent_id": 0,
        "assigned_to_all": false,
        "billable": false,
        "active": true,
        "type": "regular",
        ...
      }
    },
    "users": {
      "1242515": {
        "id": 1242515,
        "first_name": "Alexander",
        "last_name": "Luzzana",
        "group_id": 144959,
        "active": true,
        ...
      }
    },
    "customfields": {
      "19142": {
        "id": 19142,
        "required": false,
        "type": "timesheet",
        ...
      },
      "19144": {
        "id": 19144,
        "required": false,
        "type": "timesheet",
        ...
      }
    },
    "files": {
      "50692": {
        "id": 50692,
        "uploaded_by_user_id": 1242515,
        "file_name": "selfie.jpg",
        "active": true,
        ...
      },
      "44878": {
        "id": 44878,
        "uploaded_by_user_id": 1242515,
        "file_name": "selfie.jpg",
        "active": true,
        ...
      }
    }
  }
}

Add one or more timesheets to your company.

HTTP Request

posthttps://rest.tsheets.com/api/v1/timesheets

Properties

Pass an array of timesheet objects as the value to a 'data' property (see example).


All Timesheets

user_id
required
Int User id that this timesheet will be recorded against.
jobcode_id
required
Int Jobcode id that you'd like this timesheet to be recorded against.
type
required
String Either 'regular' or 'manual'.


Regular Timesheets

start
required
String Start time of the timesheet, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm). Time should reflect the user's local time.
end
required
String End time of the timesheet, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm). Time should reflect the user's local time.


Manual Timesheets

duration
required
Int Number of seconds that you'd like to record against this manual timesheet. Will get converted to hours, rounded to the nearest 2 decimal places when the timesheet is saved.
date
required
String YYYY-MM-DD formatted date string. Date you'd like the manual timesheet recorded against.

For a full list of the properties that may be set on a timesheet, see the Timesheet object.

Status Codes

Each timesheet that is created will come back with a _status_code and _status_message that will indicate whether the timesheet was created successfully. If there was a problem creating a timesheet, there may also be an additional field, _status_extra, which will contain more details about the failure.

200 OK. Timesheet was created successfully.
201 Fulfilled. Timesheet was created successfully. Other timesheets may have been modified as a result (i.e. due to timesheet splits or an automatic Lunch Break). Be sure to process entries for timesheets or timesheets_deleted in the supplemental_data portion of the response.
403 Forbidden. TS-1006: User is not allowed to track time.
406 Not Acceptable. Conflict exists with another timesheet. See the _status_extra value for more detail.
417 Expectation Failed. Something was wrong or missing with the properties supplied for this timesheet. See the _status_extra value for more detail.

Update Timesheets

Example: Change some information for each of these timesheets.

Request Body

{
  "data": [{
    "id": 136022168,
    "end": "2018-08-08T14:00:00-07:00",
    "jobcode_id": "18081060"
  }, {
    "id": 136022240,
    "date": "2018-08-08",
    "duration": 15552
  }]
}

Request

curl -X PUT \
  https://rest.tsheets.com/api/v1/timesheets \
  -H 'Authorization: Bearer <TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '<REQUEST BODY>'
var client = new RestClient("https://rest.tsheets.com/api/v1/timesheets");
var request = new RestRequest(Method.PUT);
request.AddHeader("Authorization", "Bearer <TOKEN>");
request.AddHeader("Content-Type", "application/json");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/timesheets")
Dim request = New RestRequest(Method.PUT)
request.AddHeader("Authorization", "Bearer <TOKEN>")
request.AddHeader("Content-Type", "application/json")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<REQUEST BODY>");
Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/timesheets")
  .put(body)
  .addHeader("Authorization", "Bearer <TOKEN>")
  .addHeader("Content-Type", "application/json")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/timesheets?modified_since=2018-01-01T00:00:00-06:00",
  "method": "PUT",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
    "Content-Type", "application/json",
  },
  "processData": false,
  "data": "<REQUEST BODY>"
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'PUT',
  url: 'https://rest.tsheets.com/api/v1/timesheets',
  headers: 
  { 
     'Authorization': 'Bearer <TOKEN>',
     'Content-Type': 'application/json',
  },
  body: '<REQUEST BODY>',
  json: true };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/timesheets');
$request->setMethod(HTTP_METH_PUT);

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
  'Content-Type' => 'application/json',
));

$request->setBody('<REQUEST BODY>');

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/timesheets")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <TOKEN>',
request["Content-Type"] = 'application/json',
request.body = "<REQUEST BODY>"

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/timesheets"

payload = "<REQUEST BODY>"
headers = {
    'Authorization': 'Bearer <TOKEN>',
    'Content-Type': 'application/json',
    }

response = requests.request("PUT", url, data=payload, headers=headers)

print(response.text)
package main

import (
  "fmt"
  "strings"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/timesheets"

  payload := strings.NewReader("<REQUEST BODY>")

  req, _ := http.NewRequest("PUT", 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, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))

}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
   "Content-Type": "application/json",
]
let parameters = <REQUEST BODY> as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(
  url: NSURL(string: "http://rest.tsheets.com/api/v1/timesheets")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "PUT"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest,
  completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');
$client->addHeader('Content-Type', 'application/json');

$req = '<REQUEST BODY>';

$url="http://rest.tsheets.com/api/v1/timesheets"; 

$client->PUT($url, $req);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "timesheets": {
      "1": {
        "_status_code": 200,
        "_status_message": "Updated",
        "id": 136022168,
        "user_id": 1242509,
        "jobcode_id": 18081060,
        "start": "2018-08-08T09:00:00-06:00",
        "end": "2018-08-08T15:00:00-06:00",
        "duration": 21600,
        "date": "2018-08-08",
        "tz": -7,
        "tz_str": "tsMT",
        "type": "regular",
        "location": "(Eagle, ID?)",
        "active": "0",
        "locked": 0,
        "notes": "",
        "customfields": {
          "19142": "",
          "19144": ""
        },
        "attached_files": [
          50692,
          44878
        ],
        "last_modified": "2018-08-09T21:30:10+00:00"
      },
      "2": {
        "_status_code": 200,
        "_status_message": "Updated",
        "id": 136022240,
        "user_id": 1242515,
        "jobcode_id": 0,
        "start": "2018-08-08T08:00:00-06:00",
        "end": "2018-08-08T12:19:12-06:00",
        "duration": 15552,
        "date": "2018-08-08",
        "tz": -6,
        "tz_str": "tsMT",
        "type": "manual",
        "location": "(Eagle, ID?)",
        "active": "0",
        "locked": 0,
        "notes": "",
        "customfields": {
          "19142": "",
          "19144": ""
        },
        "attached_files": [
          50692,
          44878
        ],
        "last_modified": "2018-08-09T21:30:12+00:00"
      }
    }
  },
  "supplemental_data": {
    "jobcodes": {
      "18081060": {
        "id": 18081060,
        "parent_id": 0,
        "assigned_to_all": true,
        "billable": false,
        "active": true,
        ...
      }
    },
    "users": {
      "1242509": {
        "id": 1242509,
        "first_name": "Courtney",
        "last_name": "Ballenger",
        "group_id": 144961,
        "active": true,
        ...
      },
      "1242515": {
        "id": 1242515,
        "first_name": "Alexander",
        "last_name": "Luzzana",
        "group_id": 144959,
        "active": true,
        ...
      }
    },
    "customfields": {
      "19142": {
        "id": 19142,
        "required": false,
        "name": "Custom Field 1",
        "type": "timesheet",
        ...
      },
      "19144": {
        "id": 19144,
        "required": false,
        "name": "Custom Field 2",
        "type": "timesheet",
        ...
      }
    },
    "files": {
      "50692": {
        "id": 50692,
        "uploaded_by_user_id": 1242515,
        "file_name": "minion.jpg",
        "active": true,
        ...
      },
      "44878": {
        "id": 44878,
        "uploaded_by_user_id": 1242515,
        "file_name": "minion.jpg",
        "active": true,
        ...
      }
    }
  }
}

Edit one or more timesheets in your company.

HTTP Request

puthttps://rest.tsheets.com/api/v1/timesheets

Properties

Pass an array of timesheet objects as the value to a 'data' property (see example).

When editing a timesheet, you must uniquely identify the timesheet by passing in its id. All other properties defined below may be passed in to the request with a new value in order to change it. If the value passed in is the same as it was previously, or if a particular property is not passed in at all, it will be ignored.


All Timesheets

id
required
Int Timesheet id of the timesheet that you are going to edit.
jobcode_id
optional
Int Jobcode id that you'd like this timesheet to be recorded against.
notes
optional
String Notes you'd like associated with this timesheet.
customfields
optional
JSON Object A key/value map of customfield ids to the customfield items that are associated with the timesheet.

Note: The customfields property is only applicable if the Advanced Tracking Add-on is installed.
attached_files
optional
Array Ids of files attached to this timesheet.


Regular Timesheets

start
optional
String Start time of the timesheet, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm). Time should reflect the user's local time.
end
optional
String End time of the timesheet, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm). Time should reflect the user's local time. Enter an empty string to make the timesheet active.
origin_hint_start
optional
String This is a string that will be logged as part of the timesheet history when someone is put on the clock, or a timesheet is created with both start and end.
origin_hint_end
optional
String This is a string that will be logged as part of the timesheet history when someone is taken off the clock, or a timesheet is created with both start and end.


Manual Timesheets

duration
optional
Int Number of seconds that you'd like to record against this manual timesheet. Will get converted to hours, rounded to the nearest 2 decimal places when the timesheet is saved.
date
optional
String YYYY-MM-DD formatted date string. Date you'd like the manual timesheet recorded against.

Status Codes

Each timesheet that is edited will come back with a _status_code and _status_message that will indicate whether the timesheet was edited successfully. If there was a problem editing a timesheet, there may also be an additional field, _status_extra, which will contain more details about the failure.

200 OK. Timesheet was edited successfully.
201 Fulfilled. Timesheet was created successfully. Other timesheets may have been modified as a result (i.e. due to timesheet splits or an automatic Lunch Break). Be sure to process entries for timesheets or timesheets_deleted in the supplemental_data portion of the response.
404 Not Found. Timesheet either has never existed or has been deleted.
409 Conflict. Because a conflict would have resulted in the change requested, the timesheet was not modified. The unmodified timesheet's properties will be included in the response, to make it easy to revert to the unmodified version of the timesheet.
417 Expectation Failed. Something was wrong or missing with the properties supplied for this timesheet. See the _status_extra value for more detail.

Delete Timesheets

Example: Delete two timesheets.

Request

curl -X DELETE "https://rest.tsheets.com/api/v1/timesheets?ids=135694294,135694494"
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/timesheets?ids=135694294,135694494");
var request = new RestRequest(Method.DELETE);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/timesheets?ids=135694294,135694494")
Dim request = New RestRequest(Method.[DELETE])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/timesheets?ids=135694294,135694494")
  .delete()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/timesheets?ids=135694294,135694494",
  "method": "DELETE",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'DELETE',
  url: 'https://rest.tsheets.com/api/v1/timesheets',
  qs: {
    ids: '135694294,135694494',
  },
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/timesheets');
$request->setMethod(HTTP_METH_DELETE);

$request->setQueryData(array(
  'ids' => '135694294,135694494',
));

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/timesheets?ids=135694294,135694494")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Delete.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/timesheets"

querystring = {
  "ids":"135694294,135694494",
}

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/timesheets?ids=135694294,135694494"

  req, _ := http.NewRequest("DELETE", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/timesheets?ids=135694294,135694494")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "DELETE"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/timesheets?ids=135694294,135694494"; 

$client->DELETE($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "timesheets": {
      "135694294": {
        "_status_code": 200,
        "_status_message": "OK, deleted",
        "id": "135694294"
      },
      "135694494": {
        "_status_code": 200,
        "_status_message": "OK, deleted",
        "id": "135694494"
      }
    }
  }
}

Delete one or more timesheets in your company.

HTTP Request

deletehttps://rest.tsheets.com/api/v1/timesheets

Parameters

If no filters are specified at all, no timesheets are deleted.

ids
optional
Int Comma separated list of timesheet ids you'd like to delete. Note that timesheets are actually deleted, not archived.

Status Codes

Each timesheet that is deleted will come back with a _status_code and _status_message that will indicate whether the timesheet was deleted successfully. If there was a problem deleting a timesheet, there may also be an additional field, _status_extra, which will contain more details about the failure.

200 OK. Timesheet was deleted successfully.
404 Not Found. Timesheet either has never existed or has already been deleted.
409 Conflict. Because a conflict would have resulted in the change requested, the timesheet was not modified. The unmodified timesheet's properties will be included in the response, to make it easy to revert to the unmodified version of the timesheet.
417 Expectation Failed. Something went wrong for this timesheet. See the _status_extra value for more detail.

Timesheets Deleted

The Timesheets Deleted Object

Example

{
  "id": 135288460,
  "user_id": 1242509,
  "jobcode_id": 18080900,
  "start": "2018-07-18T08:09:00-06:00",
  "end": "2018-07-18T14:58:00-06:00",
  "duration": 24540,
  "date": "2018-07-18",
  "tz": -6,
  "tz_str": "tsMT",
  "type": "regular",
  "location": "(Eagle, ID?)",
  "active": "0",
  "locked": 0,
  "notes": "",
  "last_modified": "2018-08-05T21:21:55+00:00"
}

Following is a list of the properties that are common to timesheet deleted objects, and a description of each.

id
read-only
Int Id of the timesheet.
user_id
read-only
Int User id for the user that this timesheet belongs to.
jobcode_id
read-only
Int Jobcode id for the jobcode that this timesheet is recorded against.
start
read-only
String Date/time that represents the start time of this timesheet, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm)
end
read-only
String Date/time that represents the end time of this timesheet, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm)
date
read-only
String The timesheet's date, in YYYY-MM-DD format.
duration
read-only
Int The total number of seconds recorded for this timesheet.
locked
read-only
Int If greater than 0, the timesheet is locked for editing. A timesheet could be locked for various reasons, such as being exported, invoiced, etc. See note below.
notes
read-only
String Notes associated with this timesheet.
customfields
read-only
JSON object A key/value map of customfield ids to the customfield items that are associated with the timesheet.

Note: The customfields property is present only if the Advanced Tracking Add-On is installed.
created
read-only
String Date/time when this timesheet was created, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm)
last_modified
read-only
String Date/time when this timesheet was last modified, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm)
type
read-only
String Either 'regular' or 'manual'. Regular timesheets have a start & end time (duration is calculated by TSheets). Manual timesheets have a date and a duration (in seconds). Unique properties for each timesheet type are below.

Retrieve Timesheets Deleted

Example: Retrieve a list of timesheets that have been deleted since a given date.

Request

curl "https://rest.tsheets.com/api/v1/timesheets_deleted?modified_since=2018-08-04T00:00:00-06:00" \
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/timesheets_deleted?modified_since=2018-08-04T00:00:00-06:00");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/timesheets_deleted?modified_since=2018-08-04T00:00:00-06:00")
Dim request = New RestRequest(Method.[GET])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/timesheets_deleted?modified_since=2018-08-04T00:00:00-06:00")
  .get()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/timesheets_deleted?modified_since=2018-08-04T00:00:00-06:00",
  "method": "GET",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'GET',
  url: 'https://rest.tsheets.com/api/v1/timesheets_deleted',
  qs: {
    modified_since: '2018-08-04T00:00:00-06:00',
  },
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/timesheets_deleted');
$request->setMethod(HTTP_METH_GET);

$request->setQueryData(array(
  'modified_since' => '2018-08-04T00:00:00-06:00',
));

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/timesheets_deleted?modified_since=2018-08-04T00:00:00-06:00")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/timesheets_deleted"

querystring = {
  "modified_since":"2018-08-04T00:00:00-06:00",
}

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/timesheets_deleted?modified_since=2018-08-04T00:00:00-06:00"

  req, _ := http.NewRequest("GET", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/timesheets_deleted?modified_since=2018-08-04T00:00:00-06:00")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest, completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/timesheets_deleted?modified_since=2018-08-04T00:00:00-06:00"; 

$client->GET($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "timesheets_deleted": {
      "135288460": {
        "id": 135288460,
        "user_id": 1242509,
        "jobcode_id": 18080900,
        "start": "2018-07-18T08:09:00-06:00",
        "end": "2018-07-18T14:58:00-06:00",
        "duration": 24540,
        "date": "2018-07-18",
        "tz": -6,
        "tz_str": "tsMT",
        "type": "regular",
        "location": "(Eagle, ID?)",
        "active": "0",
        "locked": 0,
        "notes": "",
        "last_modified": "2018-08-05T21:21:55+00:00"
      },
      "135288102": {
        "id": 135288102,
        "user_id": 1242515,
        "jobcode_id": 17288283,
        "start": "2018-07-22T13:05:00-06:00",
        "end": "2018-07-22T18:07:00-06:00",
        "duration": 18120,
        "date": "2018-07-22",
        "tz": -6,
        "tz_str": "tsMT",
        "type": "regular",
        "location": "(Eagle, ID?)",
        "active": "0",
        "locked": 0,
        "notes": "",
        "last_modified": "2018-08-05T21:20:11+00:00"
      }
    }
  },
  "more": false,
  "supplemental_data": {
    "jobcodes": {
      "18080900": {
        "id": 18080900,
        "parent_id": 17288279,
        "assigned_to_all": false,
        "billable": false,
        "active": true,
        ...
      },
      "17288279": {
        "id": 17288279,
        "parent_id": 0,
        "assigned_to_all": false,
        "billable": false,
        "active": true,
        ...
      },
      "17288283": {
        "id": 17288283,
        "parent_id": 0,
        "assigned_to_all": false,
        "billable": false,
        "active": true,
        ...
      }
    },
    "users": {
      "1242509": {
        "id": 1242509,
        "first_name": "Courtney",
        "last_name": "Ballenger",
        "group_id": 144961,
        "active": true,
        ...
      },
      "1242515": {
        "id": 1242515,
        "first_name": "Alexander",
        "last_name": "Luzzana",
        "group_id": 144959,
        "active": true,
        ...
      }
    }
  }
}

Example: Retrieve a list of deleted timesheets that were created within a range of dates.

Request

curl "https://rest.tsheets.com/api/v1/timesheets_deleted?start_date=2018-08-01&end_date=2018-08-08" \
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/timesheets_deleted?start_date=2018-08-01&end_date=2018-08-08");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/timesheets_deleted?start_date=2018-08-01&end_date=2018-08-08")
Dim request = New RestRequest(Method.[GET])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/timesheets_deleted?start_date=2018-08-01&end_date=2018-08-08")
  .get()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/timesheets_deleted?start_date=2018-08-01&end_date=2018-08-08",
  "method": "GET",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'GET',
  url: 'https://rest.tsheets.com/api/v1/timesheets_deleted',
  qs: {
    start_date: '2018-08-01',
    end_date: '2018-08-08',
  },
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/timesheets_deleted');
$request->setMethod(HTTP_METH_GET);

$request->setQueryData(array(
  'start_date' => '2018-08-01',
  'end_date' => '2018-08-08',
));

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/timesheets_deleted?start_date=2018-08-01&end_date=2018-08-08")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/timesheets_deleted"

querystring = {
  "start_date":"2018-08-01",
  "end_date":"2018-08-08",
}

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/timesheets_deleted?start_date=2018-08-01&end_date=2018-08-08"

  req, _ := http.NewRequest("GET", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/timesheets_deleted?start_date=2018-08-01&end_date=2018-08-08")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest, completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/timesheets_deleted?start_date=2018-08-01&end_date=2018-08-08"; 

$client->GET($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "timesheets_deleted": {
      "136022048": {
        "id": 136022048,
        "user_id": 1242325,
        "jobcode_id": 0,
        "start": "2018-08-08T08:00:00-06:00",
        "end": "2018-08-08T14:00:00-06:00",
        "duration": 21600,
        "date": "2018-08-08",
        "tz": -6,
        "tz_str": "tsMT",
        "type": "manual",
        "location": "(Eagle, ID?)",
        "active": "0",
        "locked": 0,
        "notes": "",
        "last_modified": "2018-08-09T17:30:54+00:00"
      }
    }
  },
  "more": false,
  "supplemental_data": {
    "users": {
      "1242325": {
        "id": 1242325,
        "first_name": "Garrett",
        "last_name": "Mick",
        "group_id": 144959,
        "active": true,
        ...
      }
    }
  }
} 

Example: Retrieve a list of deleted timesheets with the specified ids.

Request

curl "https://rest.tsheets.com/api/v1/timesheets_deleted?ids=136022048" \
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/timesheets_deleted?ids=136022048");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/timesheets_deleted?ids=136022048")
Dim request = New RestRequest(Method.[GET])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/timesheets_deleted?ids=136022048")
  .get()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/timesheets_deleted?ids=136022048",
  "method": "GET",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'GET',
  url: 'https://rest.tsheets.com/api/v1/timesheets_deleted',
  qs: {
    ids: '136022048',
  },
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/timesheets_deleted');
$request->setMethod(HTTP_METH_GET);

$request->setQueryData(array(
  'ids' => '136022048',
));

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/timesheets_deleted?ids=136022048")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/timesheets_deleted"

querystring = {
  "ids":"136022048",
}

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/timesheets_deleted?ids=136022048"

  req, _ := http.NewRequest("GET", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/timesheets_deleted?ids=136022048")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest, completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/timesheets_deleted?ids=136022048"; 

$client->GET($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "timesheets_deleted": {
      "136022048": {
        "id": 136022048,
        "user_id": 1242325,
        "jobcode_id": 0,
        "start": "2018-08-08T08:00:00-06:00",
        "end": "2018-08-08T14:00:00-06:00",
        "duration": 21600,
        "date": "2018-08-08",
        "tz": -6,
        "tz_str": "tsMT",
        "type": "manual",
        "location": "(Eagle, ID?)",
        "active": "0",
        "locked": 0,
        "notes": "",
        "last_modified": "2018-08-09T17:30:54+00:00"
      }
    }
  },
  "more": false,
  "supplemental_data": {
    "users": {
      "1242325": {
        "id": 1242325,
        "first_name": "Garrett",
        "last_name": "Mick",
        "group_id": 144959,
        "active": true,
        ...
      }
    }
  }
}

Gets deleted timesheets records.

HTTP Request

gethttps://rest.tsheets.com/api/v1/timesheets_deleted

Filter Parameters

start_date
required (unless modified_before, modified_since, or ids is set)
String YYYY-MM-DD formatted date. Beginning date for the report data (based off the date the timesheets were created for).
end_date
required (unless modified_before, modified_since, or ids is set)
String YYYY-MM-DD formatted date. Ending date for the report data (based off the date the timesheets were created for).
ids
required (unless modified_before, modified_since, or start_date and end_date are set)
String Timesheet ids. This can be a single id, an array of ids, or a comma-separated string of ids. '' by default.
modified_since
required (unless modified_before, ids, or start_date and end_date are set)
String Only timesheets deleted since this date/time will be returned, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm).
modified_before
required (unless modified_since, ids, or start_date and end_date are set)
String Only timesheets deleted before this date/time will be returned, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm).
group_ids
optional
String This can be a single id, an array of ids, or a comma-separated string of ids. If present, only timesheets associated with the specified group(s) will be returned. '' by default.
user_ids
optional
String This can be a single id, an array of ids, or a comma-separated string of ids. If present, only timesheets associated with the specified user(s) will be returned. '' by default.
username
optional
String If present, only timesheets associated with the specified username will be returned. Overrides user_ids and group_ids. '' by default.
jobcode_ids
optional
String This can be a single id, an array of ids, or a comma-separated string of ids. If present, only timesheets recorded against the specified jobcode(s) and any children will be returned. '' by default.
jobcode_type
optional
String 'regular', 'pto', 'paid_break', 'unpaid_break', or 'all'. Default is 'all'. Only timesheets linked to a jobcode of the given type are returned.
type
optional
String 'manual', 'regular', or 'both'. 'both' is the default.
order_results_by
optional
String 'fname', 'lname', 'username', or 'date'. 'date' is the default. All are secondarily sorted by 'date', unless 'date' is the choice, in which case 'date' is the only field the timesheets are sorted by.
order_results_reverse
optional
Boolean 1 or 0. If set to 1, then results are returned in reverse order by whatever they're sorted on.
page
optional
Int Represents the page of results you'd like to retrieve. Default is 1.
per_page
optional
Int Deprecated. Use limit for new code.
Represents how many results you'd like to retrieve per request. Default is 50. Max is 50.
If a value over 50 is provided, it is ignored, and the max is used.
limit
optional
Int Represents how many results you'd like to retrieve per request. Default is 200. Max is 200.
If present, this value must be: an integer, greater than zero, and not greater than 200.
Setting limit less than 1 or greater than 200 will result in an error.

Time Off Requests

Time Off Requests are used to track paid or unpaid time off in TSheets. Requests are submitted by team members or by admins/managers on their behalf. Once they are approved, a timesheet is generated for each request entry. Then the time off timesheets can be exported or summarized in reports as usual.

The Time Off Request Object

Example

{
  "id": 1546922,
  "user_id": 423,
  "time_off_request_notes": [ 96024 ],
  "time_off_request_entries": [ 11374, 11375 ],
  "status": "pending",
  "active": true,
  "created": "2018-11-11T10:56:15-06:00",
  "last_modified": "2018-11-11T10:56:15-06:00"
}

Following is a list of the properties that belong to a time off request, and a description of each.

id
read-only
Int Id of the time off request.
user_id
read-write
Int User id for the user that this time off request belongs to.
time_off_request_notes
read-write
Int An array of Time Off Request Note ids associated with this time off request.
time_off_request_entries
read-write
Int An array of Time Off Request Entry ids associated with this time off request.
status
read-write
String One of: 'pending', 'approved', 'denied', or 'canceled'.
active
read-write
Boolean If true, this time off request is active. If false, this time off request is archived.
created
read-only
String Date/time when this time off request was created, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm).
last_modified
read-only
String Date/time when this time off request was last modified, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm).

The Time Off Request Note Object

Example

{
  "id": 96024,
  "time_off_request_id": 1546922,
  "user_id": 423,
  "active": true,
  "note": "Taking a four day weekend to go on vacation.",
  "created": "2018-11-11T10:56:15-06:00",
  "last_modified": "2018-11-11T10:56:15-06:00"
}

Following is a list of the properties that belong to a time off request note, and a description of each.

id
read-only
Int Id of the time off request note.
time_off_request_id
read-write
Int Id of the time of request that this note belong to.
user_id
read-only
Int User id for the user that created this note.
note
read-write
String The note the user wrote.
active
read-only
Boolean If true, this note is active. If false, this note is archived.
created
read-only
String Date/time when this note was created, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm).
last_modified
read-only
String Date/time when this note was last modified, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm).

Retrieve Time Off Requests

Example: Retrieve a list of all time off requests that have not been approved or denied for two specified users.

Request

curl "https://rest.tsheets.com/api/v1/time_off_requests?user_ids=423,467" \
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/time_off_requests?user_ids=423,467");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/time_off_requests?user_ids=423,467")
Dim request = New RestRequest(Method.[GET])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/time_off_requests?user_ids=423,467")
  .get()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/time_off_requests?user_ids=423,467",
  "method": "GET",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'GET',
  url: 'https://rest.tsheets.com/api/v1/time_off_requests',
  qs: {
    user_ids: '423,467',
  },
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/time_off_requests');
$request->setMethod(HTTP_METH_GET);

$request->setQueryData(array(
  'user_ids' => '423,467',
));

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/time_off_requests?user_ids=423,467")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/time_off_requests"

querystring = {
  "user_ids":"423,467",
}

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/time_off_requests?user_ids=423,467"

  req, _ := http.NewRequest("GET", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/time_off_requests?user_ids=423,467")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest, completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/time_off_requests?user_ids=423,467"; 

$client->GET($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "time_off_requests": {
      "1546922": {
        "id": 1546922,
        "user_id": 423,
        "time_off_request_notes": [96024],
        "time_off_request_entries": [11374, 11375],
        "status": "pending",
        "active": true,
        "created": "2018-11-11T10:56:15-06:00",
        "last_modified": "2018-11-11T10:56:15-06:00"
      },
      "1547432": {
        "id": 1547432,
        "user_id": 467,
        "time_off_request_notes": [100021],
        "time_off_request_entries": [11564],
        "status": "pending",
        "active": true,
        "created": "2018-11-12T10:05:02-06:00",
        "last_modified": "2018-11-12T10:05:02-06:00"
      }
    }
  },
  "more": false,
  "supplemental_data": {
    "users": {
      "423": {
        "id": 423,
        "first_name": "Sean",
        "last_name": "Evans",
        "group_id": 34,
        "active": true,
        "employee_number": 4,
        "salaried": false,
        "exempt": false,
        "username": "sevans",
        "email": "sevans@hotones.com",
        "payroll_id": 4,
        "hire_date": "2017-04-27",
        "term_date": "0000-00-00",
        "job_title": "",
        "gender": "",
        "last_modified": "2017-09-21T15:52:00-06:00",
        "last_active": "2018-11-12T11:45:15-06:00",
        "created": "2017-04-27T07:23:44-06:00",
        "mobile_number": ""
      },
      "467": {
        "id": 467,
        "first_name": "Guy",
        "last_name": "Fieri",
        "group_id": 34,
        "active": true,
        "employee_number": 5,
        "salaried": false,
        "exempt": false,
        "username": "gfieri",
        "email": "gfieri@foodnetwork.com",
        "payroll_id": 5,
        "hire_date": "2017-07-12",
        "term_date": "0000-00-00",
        "job_title": "",
        "gender": "",
        "last_modified": "2017-09-21T15:02:00-06:00",
        "last_active": "2018-11-12T13:12:01-06:00",
        "created": "2017-07-12T08:05:22-06:00",
        "mobile_number": ""
      }
    },
    "time_off_request_notes" : {
      "96024": {
       "id": 96024,
       "time_off_request_id": 1546922,
       "user_id": 423,
       "active": true,
       "note": "Taking a four day weekend to go on vacation.",
       "created": "2018-11-11T10:56:15-06:00",
       "last_modified": "2018-11-11T10:56:15-06:00"
      },
      "100021": {
       "id": 100021,
       "time_off_request_id": 1547432,
       "user_id": 467,
       "active": true,
       "note": "It's my birthday!",
       "created": "2018-11-12T10:05:02-06:00",
       "last_modified": "2018-11-12T10:05:02-06:00"
      }
    },
    "time_off_request_entries": {
      "11374": {
        "id": 11374,
        "time_off_request_id": 1546922,
        "status": "pending",
        "approver_user_id": 0,
        "date": "2018-11-15",
        "entry_method": "manual",
        "duration": 28800,
        "start_time": "2018-11-15T00:00:00-07:00",
        "end_time": "2018-11-15T23:59:59-07:00",
        "tz_string": "America/Denver",
        "jobcode_id": 1345687,
        "user_id": 423,
        "approved_timesheet_id": 0,
        "active": true,
        "created": "2018-11-11T10:56:15-06:00",
        "last_modified": "2018-11-11T10:56:15-06:00"
      },
      "11375": {
        "id": 11375,
        "time_off_request_id": 1546922,
        "status": "pending",
        "approver_user_id": 0,
        "date": "2018-11-16",
        "entry_method": "manual",
        "duration": 28800,
        "start_time": "2018-11-16T00:00:00-07:00",
        "end_time": "2018-11-16T23:59:59-07:00",
        "tz_string": "America/Denver",
        "jobcode_id": 1345687,
        "user_id": 423,
        "approved_timesheet_id": 0,
        "active": true,
        "created": "2018-11-11T10:56:15-06:00",
        "last_modified": "2018-11-11T10:56:15-06:00"
      },
      "11564": {
        "id": 11564,
        "time_off_request_id": 1547432,
        "status": "pending",
        "approver_user_id": 0,
        "date": "2018-01-22",
        "entry_method": "manual",
        "duration": 28800,
        "start_time": "",
        "end_time": "",
        "jobcode_id": 1345645,
        "user_id": 467,
        "approved_timesheet_id": 0,
        "active": true,
        "created": "2018-11-12T10:05:02-06:00",
        "last_modified": "2018-11-12T10:05:02-06:00"
      }
    }
  }
}

Retrieves a list of time off requests associated with your company, with filters to narrow down the results.

HTTP Request

gethttps://rest.tsheets.com/api/v1/time_off_requests

Filter Parameters

If no filters are set, all time off requests for the requesting user (based on the Access-Token) and users they can manage will be returned.

ids
optional
Int Comma separated list of one or more time off request ids you'd like to filter on. Only time off requests with an id set to one of these values will be returned.
user_ids
optional
Int Comma separated list of one or more user ids. Only time off requests linked to one of these user ids will be returned. Only administrators or group managers may retrieve time off requests for users other than themselves. Furthermore, administrators or group managers may only retrieve time off requests for users that belong to their company.
supplemental_data
optional
String 'yes' or 'no'. Default is 'yes'. Indicates whether supplemental data should be returned.
per_page
optional
Int Deprecated. Use limit for new code.
Represents how many results you'd like to retrieve per request. Default is 50. Max is 50.
If a value over 50 is provided, it is ignored, and the max is used.
limit
optional
Int Represents how many results you'd like to retrieve per request. Default is 200. Max is 200.
If present, this value must be: an integer, greater than zero, and not greater than 200.
Setting limit less than 1 or greater than 200 will result in an error.
page
optional
Int Represents the page of results you'd like to retrieve. Default is 1.

Create Time Off Requests

Example: Adding a time off request for 2 days, with notes.

Request Body

{
  "data": [{
    "time_off_request_notes": [{
        "note": "Taking a four day weekend to go on vacation."
    }],
    "time_off_request_entries": [{
      "date": "2018-11-15",
      "entry_method": "manual",
      "duration": 28800,
      "jobcode_id": 1345687
    }, {
      "date": "2018-11-16",
      "entry_method": "manual",
      "duration": 28800,
      "jobcode_id": 1345687
    }]
  }]
}


Request

curl -X POST \
  https://rest.tsheets.com/api/v1/time_off_requests \
  -H 'Authorization: Bearer <TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '<REQUEST BODY>'
var client = new RestClient("https://rest.tsheets.com/api/v1/time_off_requests");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <TOKEN>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "<REQUEST BODY>", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/time_off_requests")
Dim request = New RestRequest(Method.POST)
request.AddHeader("Authorization", "Bearer <TOKEN>")
request.AddHeader("Content-Type", "application/json")
request.AddParameter("application/json", "<REQUEST BODY>", ParameterType.RequestBody);
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<REQUEST BODY>");
Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/time_off_requests")
  .post(body)
  .addHeader("Authorization", "Bearer <TOKEN>")
  .addHeader("Content-Type", "application/json")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/time_off_requests?user_ids=423,467",
  "method": "POST",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
    "Content-Type", "application/json",
  },
  "processData": false,
  "data": "<REQUEST BODY>"
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'POST',
  url: 'https://rest.tsheets.com/api/v1/time_off_requests',
  headers: 
  { 
     'Authorization': 'Bearer <TOKEN>',
     'Content-Type': 'application/json',
  },
  body: '<REQUEST BODY>',
  json: true };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/time_off_requests');
$request->setMethod(HTTP_METH_POST);

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
  'Content-Type' => 'application/json',
));

$request->setBody('<REQUEST BODY>');

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/time_off_requests")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <TOKEN>',
request["Content-Type"] = 'application/json',
request.body = "<REQUEST BODY>"

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/time_off_requests"

payload = "<REQUEST BODY>"
headers = {
    'Authorization': 'Bearer <TOKEN>',
    'Content-Type': 'application/json',
    }

response = requests.request("POST", url, data=payload, headers=headers)

print(response.text)
package main

import (
  "fmt"
  "strings"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/time_off_requests"

  payload := strings.NewReader("<REQUEST BODY>")

  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, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))

}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
   "Content-Type": "application/json",
]
let parameters = <REQUEST BODY> as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/time_off_requests")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest,
  completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');
$client->addHeader('Content-Type', 'application/json');

$req = '<REQUEST BODY>';

$url="https://rest.tsheets.com/api/v1/time_off_requests"; 

$client->POST($url, $req);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "time_off_requests": {
      "1546922": {
        "_status_code": 200,
        "_status_message": "Created",
        "id": 1546922,
        "user_id": 423,
        "time_off_request_notes": [96024],
        "time_off_request_entries": [11374, 11375],
        "status": "pending",
        "active": true,
        "created": "2018-11-11T10:56:15-06:00",
        "last_modified": "2018-11-11T10:56:15-06:00"
      }
    }
  },
  "supplemental_data": {
    "users": {
      "423": {
        "id": 423,
        "first_name": "Sean",
        "last_name": "Evans",
        "group_id": 34,
        "active": true,
        "employee_number": 4,
        "salaried": false,
        "exempt": false,
        "username": "sevans",
        "email": "sevans@hotones.com",
        "payroll_id": "4",
        "hire_date": "2017-04-27",
        "term_date": "0000-00-00",
        "job_title": "",
        "gender": "",
        "last_modified": "2017-09-21T15:52:00-06:00",
        "last_active": "2018-11-12T11:45:15-06:00",
        "created": "2017-04-27T07:23:44-06:00",
        "mobile_number": ""
      }
    },
    "time_off_request_notes": {
      "96024": {
        "id": 96024,
        "time_off_request_id": 1546922,
        "user_id": 423,
        "active": true,
        "note": "Taking a four day weekend to go on vacation.",
        "created": "2018-11-11T10:56:15-06:00",
        "last_modified": "2018-11-11T10:56:15-06:00"
      }
    },
    "time_off_request_entries": {
      "11374": {
        "id": 11374,
        "time_off_request_id": 1546922,
        "status": "pending",
        "approver_user_id": 0,
        "date": "2018-11-15",
        "entry_method": "manual",
        "duration": 28800,
        "start_time": "2018-11-15T00:00:00-07:00",
        "end_time": "2018-11-15T23:59:59-07:00",
        "tz_string": "America/Denver",
        "jobcode_id": 1345687,
        "user_id": 423,
        "approved_timesheet_id": 0,
        "active": true,
        "created": "2018-11-11T10:56:15-06:00",
        "last_modified": "2018-11-11T10:56:15-06:00"
      },
      "11375": {
        "id": 11375,
        "time_off_request_id": 1546922,
        "status": "pending",
        "approver_user_id": 0,
        "date": "2018-11-16",
        "entry_method": "manual",
        "duration": 28800,
        "start_time": "2018-11-16T00:00:00-07:00",
        "end_time": "2018-11-16T23:59:59-07:00",
        "tz_string": "America/Denver",
        "jobcode_id": 1345687,
        "user_id": 423,
        "approved_timesheet_id": 0,
        "active": true,
        "created": "2018-11-11T10:56:15-06:00",
        "last_modified": "2018-11-11T10:56:15-06:00"
      }
    }
  }
}

Add one or more time off requests.

HTTP Request

posthttps://rest.tsheets.com/api/v1/time_off_requests

Properties

Pass an array of Time Off Request objects as the value to a 'data' property (see example).

time_off_request_entries
required
Time Off Request Entry An array of time off request entries for this time off request.
user_id
optional
Int Defaults to the requesting user (based on the Access Token). Only administrators or group managers may add time off requests for users other than themselves. Furthermore, administrators or group managers may only add time off requests for users that belong to their company.
time_off_request_notes
optional
Time Off Request Note Defaults to empty. An array of notes for this time off request.

For a full list of the properties that may be set on a time off request, see The Time Off Requests Object.

Status Codes

Each time off request that is created will come back with a _status_code and _status_message that will indicate whether the time off request was created successfully. If there was a problem creating a time off request, there may also be an additional field, _status_extra, which will contain more details about the failure.

200 OK. Time off request was created successfully.
403 Permission Denied. The requesting user does not have permission to create the time off request for this user.
417 Expectation Failed. Something was wrong or missing with the properties supplied for this time off request. See the _status_extra value for more detail.

Update Time Off Requests

Example: Add a new note to an existing time off request.

Request Body

{
  "data": [{
    "id": 1546922,
    "time_off_request_notes": [{
      "note": "I will have Guy fill in on the show for Friday."
    }
  }]
}

Request

curl -X PUT \
  https://rest.tsheets.com/api/v1/time_off_requests \
  -H 'Authorization: Bearer <TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '<REQUEST BODY>'
var client = new RestClient("https://rest.tsheets.com/api/v1/time_off_requests");
var request = new RestRequest(Method.PUT);
request.AddHeader("Authorization", "Bearer <TOKEN>");
request.AddHeader("Content-Type", "application/json");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/time_off_requests")
Dim request = New RestRequest(Method.PUT)
request.AddHeader("Authorization", "Bearer <TOKEN>")
request.AddHeader("Content-Type", "application/json")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<REQUEST BODY>");
Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/time_off_requests")
  .put(body)
  .addHeader("Authorization", "Bearer <TOKEN>")
  .addHeader("Content-Type", "application/json")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/time_off_requests?user_ids=423,467",
  "method": "PUT",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
    "Content-Type", "application/json",
  },
  "processData": false,
  "data": "<REQUEST BODY>"
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'PUT',
  url: 'https://rest.tsheets.com/api/v1/time_off_requests',
  headers: 
  { 
     'Authorization': 'Bearer <TOKEN>',
     'Content-Type': 'application/json',
  },
  body: '<REQUEST BODY>',
  json: true };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/time_off_requests');
$request->setMethod(HTTP_METH_PUT);

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
  'Content-Type' => 'application/json',
));

$request->setBody('<REQUEST BODY>');

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/time_off_requests")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <TOKEN>',
request["Content-Type"] = 'application/json',
request.body = "<REQUEST BODY>"

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/time_off_requests"

payload = "<REQUEST BODY>"
headers = {
    'Authorization': 'Bearer <TOKEN>',
    'Content-Type': 'application/json',
    }

response = requests.request("PUT", url, data=payload, headers=headers)

print(response.text)
package main

import (
  "fmt"
  "strings"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/time_off_requests"

  payload := strings.NewReader("<REQUEST BODY>")

  req, _ := http.NewRequest("PUT", 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, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))

}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
   "Content-Type": "application/json",
]
let parameters = <REQUEST BODY> as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(
  url: NSURL(string: "http://rest.tsheets.com/api/v1/time_off_requests")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "PUT"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest,
  completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');
$client->addHeader('Content-Type', 'application/json');

$req = '<REQUEST BODY>';

$url="http://rest.tsheets.com/api/v1/time_off_requests"; 

$client->PUT($url, $req);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "time_off_requests": {
      "1546922": {
        "_status_code": 200,
        "_status_message": "Updated",
        "id": 1546922,
        "user_id": 423,
        "time_off_request_notes": [96024, 96132],
        "time_off_request_entries": [11374, 11375],
        "status": "pending",
        "active": true,
        "created": "2018-11-11T10:56:15-06:00",
        "last_modified": "2018-11-12T09:13:44-06:00"
      }
    }
  },
  "supplemental_data": {
    "users": {
      "423": {
        "id": 423,
        "first_name": "Sean",
        "last_name": "Evans",
        "group_id": 34,
        "active": true,
        "employee_number": 4,
        "salaried": false,
        "exempt": false,
        "username": "sevans",
        "email": "sevans@hotones.com",
        "payroll_id": 4,
        "hire_date": "2017-04-27",
        "term_date": "0000-00-00",
        "job_title": "",
        "gender": "",
        "last_modified": "2017-09-21T15:52:00-06:00",
        "last_active": "2018-11-12T11:45:15-06:00",
        "created": "2017-04-27T07:23:44-06:00",
        "mobile_number": ""
      }
    },
    "time_off_request_notes": {
      "96024": {
        "id": 96024,
        "time_off_request_id": 1546922,
        "user_id": 423,
        "active": true,
        "note": "Taking a four day weekend to go on vacation.",
        "created": "2018-11-11T10:56:15-06:00",
        "last_modified": "2018-11-11T10:56:15-06:00"
      },
      "96132": {
        "id": 96132,
        "time_off_request_id": 1546922,
        "user_id": 423,
        "active": true,
        "note": "I will have Guy fill in on the show for Friday.",
        "created": "2018-11-12T09:13:44-06:00"
      }
    },
    "time_off_request_entries": {
      "11374": {
        "id": 11374,
        "time_off_request_id": 1546922,
        "status": "pending",
        "approver_user_id": 0,
        "date": "2018-11-15",
        "entry_method": "manual",
        "duration": 28800,
        "start_time": "",
        "end_time": "",
        "jobcode_id": 1345687,
        "user_id": 423,
        "approved_timesheet_id": 0,
        "active": true,
        "created": "2018-11-11T10:56:15-06:00",
        "last_modified": "2018-11-11T10:56:15-06:00"
      },
      "11375": {
        "id": 11375,
        "time_off_request_id": 1546922,
        "status": "pending",
        "approver_user_id": 0,
        "date": "2018-11-16",
        "entry_method": "manual",
        "duration": 28800,
        "start_time": "",
        "end_time": "",
        "jobcode_id": 1345687,
        "user_id": 423,
        "approved_timesheet_id": 0,
        "active": true,
        "created": "2018-11-11T10:56:15-06:00",
        "last_modified": "2018-11-11T10:56:15-06:00"
      }
    }
  }
}


Example: Approve a time off request. Note: this will also set the status to 'approved' on all entries.

Request Body

{
  "data": [{
    "id": 1546922,
    "status": "approved"
  }]
}

Request

curl -X PUT \
  https://rest.tsheets.com/api/v1/time_off_requests \
  -H 'Authorization: Bearer <TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '<REQUEST BODY>'
var client = new RestClient("https://rest.tsheets.com/api/v1/time_off_requests");
var request = new RestRequest(Method.PUT);
request.AddHeader("Authorization", "Bearer <TOKEN>");
request.AddHeader("Content-Type", "application/json");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/time_off_requests")
Dim request = New RestRequest(Method.PUT)
request.AddHeader("Authorization", "Bearer <TOKEN>")
request.AddHeader("Content-Type", "application/json")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<REQUEST BODY>");
Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/time_off_requests")
  .put(body)
  .addHeader("Authorization", "Bearer <TOKEN>")
  .addHeader("Content-Type", "application/json")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/time_off_requests?user_ids=423,467",
  "method": "PUT",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
    "Content-Type", "application/json",
  },
  "processData": false,
  "data": "<REQUEST BODY>"
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'PUT',
  url: 'https://rest.tsheets.com/api/v1/time_off_requests',
  headers: 
  { 
     'Authorization': 'Bearer <TOKEN>',
     'Content-Type': 'application/json',
  },
  body: '<REQUEST BODY>',
  json: true };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/time_off_requests');
$request->setMethod(HTTP_METH_PUT);

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
  'Content-Type' => 'application/json',
));

$request->setBody('<REQUEST BODY>');

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/time_off_requests")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <TOKEN>',
request["Content-Type"] = 'application/json',
request.body = "<REQUEST BODY>"

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/time_off_requests"

payload = "<REQUEST BODY>"
headers = {
    'Authorization': 'Bearer <TOKEN>',
    'Content-Type': 'application/json',
    }

response = requests.request("PUT", url, data=payload, headers=headers)

print(response.text)
package main

import (
  "fmt"
  "strings"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/time_off_requests"

  payload := strings.NewReader("<REQUEST BODY>")

  req, _ := http.NewRequest("PUT", 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, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))

}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
   "Content-Type": "application/json",
]
let parameters = <REQUEST BODY> as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(
  url: NSURL(string: "http://rest.tsheets.com/api/v1/time_off_requests")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "PUT"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest,
  completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');
$client->addHeader('Content-Type', 'application/json');

$req = '<REQUEST BODY>';

$url="http://rest.tsheets.com/api/v1/time_off_requests"; 

$client->PUT($url, $req);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "time_off_requests": {
      "1546922": {
        "_status_code": 200,
        "_status_message": "Updated",
        "id": 1546922,
        "user_id": 423,
        "time_off_request_notes": [96024, 96132],
        "time_off_request_entries": [11374, 11375],
        "status": "approved",
        "active": true,
        "created": "2018-11-11T10:56:15-06:00",
        "last_modified": "2018-11-12T14:58:22-06:00"
      }
    }
  },
  "supplemental_data": {
    "users": {
      "417": {
        "id": 417,
        "first_name": "Adam",
        "last_name": "Manager",
        "group_id": 34,
        "active": true,
        "employee_number": 2,
        "salaried": false,
        "exempt": false,
        "username": "amanager",
        "email": "amanager@hotones.com",
        "payroll_id": 2,
        "hire_date": "2017-01-06",
        "term_date": "0000-00-00",
        "job_title": "",
        "gender": "",
        "last_modified": "2017-08-16T09:14:02-06:00",
        "last_active": "2018-11-12T15:23:22-06:00",
        "created": "2017-01-06T10:09:12-06:00",
        "mobile_number": ""
      },
      "423": {
        "id": 423,
        "first_name": "Sean",
        "last_name": "Evans",
        "group_id": 34,
        "active": true,
        "employee_number": 4,
        "salaried": false,
        "exempt": false,
        "username": "sevans",
        "email": "sevans@hotones.com",
        "payroll_id": 4,
        "hire_date": "2017-04-27",
        "term_date": "0000-00-00",
        "job_title": "",
        "gender": "",
        "last_modified": "2017-09-21T15:52:00-06:00",
        "last_active": "2018-11-12T11:45:15-06:00",
        "created": "2017-04-27T07:23:44-06:00",
        "mobile_number": ""
      }
    },
    "time_off_request_notes": {
      "96024": {
        "id": 96024,
        "time_off_request_id": 1546922,
        "user_id": 423,
        "active": true,
        "note": "Taking a four day weekend to go on vacation.",
        "created": "2018-11-11T10:56:15-06:00",
        "last_modified": "2018-11-11T10:56:15-06:00"
      },
      "96132": {
        "id": 96132,
        "time_off_request_id": 1546922,
        "user_id": 423,
        "active": true,
        "note": "I will have Guy fill in on the show for Friday.",
        "created": "2018-11-12T09:13:44-06:00",
        "last_modified": "2018-11-12T09:13:44-06:00"
      }
    },
    "time_off_request_entries": {
      "11374": {
        "id": 11374,
        "time_off_request_id": 1546922,
        "status": "approved",
        "approver_user_id": 417,
        "date": "2018-11-15",
        "entry_method": "manual",
        "duration": 28800,
        "start_time": "2018-11-15T00:00:00-07:00",
        "end_time": "2018-11-15T23:59:59-07:00",
        "tz_string": "America/Denver",
        "jobcode_id": 1345687,
        "user_id": 423,
        "approved_timesheet_id": 563431,
        "active": true,
        "created": "2018-11-11T10:56:15-06:00",
        "last_modified": "2018-11-12T14:58:22-06:00"
      },
      "11375": {
        "id": 11375,
        "time_off_request_id": 1546922,
        "status": "approved",
        "approver_user_id": 417,
        "date": "2018-11-16",
        "entry_method": "manual",
        "duration": 28800,
        "start_time": "2018-11-16T00:00:00-07:00",
        "end_time": "2018-11-16T23:59:59-07:00",
        "tz_string": "America/Denver",
        "jobcode_id": 1345687,
        "user_id": 423,
        "approved_timesheet_id": 563432,
        "active": true,
        "created": "2018-11-11T10:56:15-06:00",
        "last_modified": "2018-11-12T14:58:22-06:00"
      }
    }
  }
}


Example: Cancel a time off request. Note: this will also set the status to 'canceled' on all entries.

Request Body

{
  "data": [{
    "id": 1546922,
    "status": "canceled"
  }]
}

Request

curl -X PUT \
  https://rest.tsheets.com/api/v1/time_off_requests \
  -H 'Authorization: Bearer <TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '<REQUEST BODY>'
var client = new RestClient("https://rest.tsheets.com/api/v1/time_off_requests");
var request = new RestRequest(Method.PUT);
request.AddHeader("Authorization", "Bearer <TOKEN>");
request.AddHeader("Content-Type", "application/json");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/time_off_requests")
Dim request = New RestRequest(Method.PUT)
request.AddHeader("Authorization", "Bearer <TOKEN>")
request.AddHeader("Content-Type", "application/json")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<REQUEST BODY>");
Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/time_off_requests")
  .put(body)
  .addHeader("Authorization", "Bearer <TOKEN>")
  .addHeader("Content-Type", "application/json")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/time_off_requests?user_ids=423,467",
  "method": "PUT",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
    "Content-Type", "application/json",
  },
  "processData": false,
  "data": "<REQUEST BODY>"
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'PUT',
  url: 'https://rest.tsheets.com/api/v1/time_off_requests',
  headers: 
  { 
     'Authorization': 'Bearer <TOKEN>',
     'Content-Type': 'application/json',
  },
  body: '<REQUEST BODY>',
  json: true };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/time_off_requests');
$request->setMethod(HTTP_METH_PUT);

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
  'Content-Type' => 'application/json',
));

$request->setBody('<REQUEST BODY>');

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/time_off_requests")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <TOKEN>',
request["Content-Type"] = 'application/json',
request.body = "<REQUEST BODY>"

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/time_off_requests"

payload = "<REQUEST BODY>"
headers = {
    'Authorization': 'Bearer <TOKEN>',
    'Content-Type': 'application/json',
    }

response = requests.request("PUT", url, data=payload, headers=headers)

print(response.text)
package main

import (
  "fmt"
  "strings"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/time_off_requests"

  payload := strings.NewReader("<REQUEST BODY>")

  req, _ := http.NewRequest("PUT", 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, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))

}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
   "Content-Type": "application/json",
]
let parameters = <REQUEST BODY> as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(
  url: NSURL(string: "http://rest.tsheets.com/api/v1/time_off_requests")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "PUT"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest,
  completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');
$client->addHeader('Content-Type', 'application/json');

$req = '<REQUEST BODY>';

$url="http://rest.tsheets.com/api/v1/time_off_requests"; 

$client->PUT($url, $req);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "time_off_requests": {
      "1546922": {
        "_status_code": 200,
        "_status_message": "Updated",
        "id": 1546922,
        "user_id": 423,
        "time_off_request_notes": [96024, 96132],
        "time_off_request_entries": [11374, 11375],
        "status": "canceled",
        "active": true,
        "created": "2018-11-11T10:56:15-06:00",
        "last_modified": "2018-11-12T14:58:22-06:00"
      }
    }
  },
  "supplemental_data": {
    "users": {
      "417": {
        "id": 417,
        "first_name": "Adam",
        "last_name": "Manager",
        "group_id": 34,
        "active": true,
        "employee_number": 2,
        "salaried": false,
        "exempt": false,
        "username": "amanager",
        "email": "amanager@hotones.com",
        "payroll_id": 2,
        "hire_date": "2017-01-06",
        "term_date": "0000-00-00",
        "job_title": "",
        "gender": "",
        "last_modified": "2017-08-16T09:14:02-06:00",
        "last_active": "2018-11-12T15:23:22-06:00",
        "created": "2017-01-06T10:09:12-06:00",
        "mobile_number": ""
      },
      "423": {
        "id": 423,
        "first_name": "Sean",
        "last_name": "Evans",
        "group_id": 34,
        "active": true,
        "employee_number": 4,
        "salaried": false,
        "exempt": false,
        "username": "sevans",
        "email": "sevans@hotones.com",
        "payroll_id": 4,
        "hire_date": "2017-04-27",
        "term_date": "0000-00-00",
        "job_title": "",
        "gender": "",
        "last_modified": "2017-09-21T15:52:00-06:00",
        "last_active": "2018-11-12T11:45:15-06:00",
        "created": "2017-04-27T07:23:44-06:00",
        "mobile_number": ""
      }
    },
    "time_off_request_notes": {
      "96024": {
        "id": 96024,
        "time_off_request_id": 1546922,
        "user_id": 423,
        "active": true,
        "note": "Taking a four day weekend to go on vacation.",
        "created": "2018-11-11T10:56:15-06:00",
        "last_modified": "2018-11-11T10:56:15-06:00"
      },
      "96132": {
        "id": 96132,
        "time_off_request_id": 1546922,
        "user_id": 423,
        "active": true,
        "note": "I will have Guy fill in on the show for Friday.",
        "created": "2018-11-12T09:13:44-06:00",
        "last_modified": "2018-11-12T09:13:44-06:00"
      }
    },
    "time_off_request_entries": {
      "11374": {
        "id": 11374,
        "time_off_request_id": 1546922,
        "status": "canceled",
        "approver_user_id": 417,
        "date": "2018-11-15",
        "entry_method": "manual",
        "duration": 28800,
        "start_time": "2018-11-15T00:00:00-07:00",
        "end_time": "2018-11-15T23:59:59-07:00",
        "tz_string": "America/Denver",
        "jobcode_id": 1345687,
        "user_id": 423,
        "approved_timesheet_id": 563431,
        "active": true,
        "created": "2018-11-11T10:56:15-06:00",
        "last_modified": "2018-11-12T14:58:22-06:00"
      },
      "11375": {
        "id": 11375,
        "time_off_request_id": 1546922,
        "status": "canceled",
        "approver_user_id": 417,
        "date": "2018-11-16",
        "entry_method": "manual",
        "duration": 28800,
        "start_time": "2018-11-16T00:00:00-07:00",
        "end_time": "2018-11-16T23:59:59-07:00",
        "tz_string": "America/Denver",
        "jobcode_id": 1345687,
        "user_id": 423,
        "approved_timesheet_id": 563432,
        "active": true,
        "created": "2018-11-11T10:56:15-06:00",
        "last_modified": "2018-11-12T14:58:22-06:00"
      }
    }
  }
}


Example: Archive a time off request. Note: this will set active to 'false' on and all entries.

Request Body

{
 "data": [{
    "id"  1546922,
    "active": false
  }]
}

Request

curl -X PUT \
  https://rest.tsheets.com/api/v1/time_off_requests \
  -H 'Authorization: Bearer <TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '<REQUEST BODY>'
var client = new RestClient("https://rest.tsheets.com/api/v1/time_off_requests");
var request = new RestRequest(Method.PUT);
request.AddHeader("Authorization", "Bearer <TOKEN>");
request.AddHeader("Content-Type", "application/json");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/time_off_requests")
Dim request = New RestRequest(Method.PUT)
request.AddHeader("Authorization", "Bearer <TOKEN>")
request.AddHeader("Content-Type", "application/json")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<REQUEST BODY>");
Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/time_off_requests")
  .put(body)
  .addHeader("Authorization", "Bearer <TOKEN>")
  .addHeader("Content-Type", "application/json")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/time_off_requests?user_ids=423,467",
  "method": "PUT",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
    "Content-Type", "application/json",
  },
  "processData": false,
  "data": "<REQUEST BODY>"
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'PUT',
  url: 'https://rest.tsheets.com/api/v1/time_off_requests',
  headers: 
  { 
     'Authorization': 'Bearer <TOKEN>',
     'Content-Type': 'application/json',
  },
  body: '<REQUEST BODY>',
  json: true };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/time_off_requests');
$request->setMethod(HTTP_METH_PUT);

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
  'Content-Type' => 'application/json',
));

$request->setBody('<REQUEST BODY>');

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/time_off_requests")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <TOKEN>',
request["Content-Type"] = 'application/json',
request.body = "<REQUEST BODY>"

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/time_off_requests"

payload = "<REQUEST BODY>"
headers = {
    'Authorization': 'Bearer <TOKEN>',
    'Content-Type': 'application/json',
    }

response = requests.request("PUT", url, data=payload, headers=headers)

print(response.text)
package main

import (
  "fmt"
  "strings"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/time_off_requests"

  payload := strings.NewReader("<REQUEST BODY>")

  req, _ := http.NewRequest("PUT", 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, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))

}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
   "Content-Type": "application/json",
]
let parameters = <REQUEST BODY> as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(
  url: NSURL(string: "http://rest.tsheets.com/api/v1/time_off_requests")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "PUT"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest,
  completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');
$client->addHeader('Content-Type', 'application/json');

$req = '<REQUEST BODY>';

$url="http://rest.tsheets.com/api/v1/time_off_requests"; 

$client->PUT($url, $req);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "time_off_requests": {
      "1546922": {
        "_status_code": 200,
        "_status_message": "Updated",
        "id": 1546922,
        "user_id": 423,
        "time_off_request_notes": [96024, 96132],
        "time_off_request_entries": [11374, 11375],
        "status": "canceled",
        "active": false,
        "created": "2018-11-11T10:56:15-06:00",
        "last_modified": "2018-11-12T09:13:44-06:00"
      }
    }
  },
  "supplemental_data": {
    "users": {
      "417": {
        "id": 417,
        "first_name": "Adam",
        "last_name": "Manager",
        "group_id": 34,
        "active": true,
        "employee_number": 2,
        "salaried": false,
        "exempt": false,
        "username": "amanager",
        "email": "amanager@hotones.com",
        "payroll_id": 2,
        "hire_date": "2017-01-06",
        "term_date": "0000-00-00",
        "job_title": "",
        "gender": "",
        "last_modified": "2017-08-16T09:14:02-06:00",
        "last_active": "2018-11-12T15:23:22-06:00",
        "created": "2017-01-06T10:09:12-06:00",
        "mobile_number": ""
      },
      "423": {
        "id": 423,
        "first_name": "Sean",
        "last_name": "Evans",
        "group_id": 34,
        "active": true,
        "employee_number": 4,
        "salaried": false,
        "exempt": false,
        "username": "sevans",
        "email": "sevans@hotones.com",
        "payroll_id": 4,
        "hire_date": "2017-04-27",
        "term_date": "0000-00-00",
        "job_title": "",
        "gender": "",
        "last_modified": "2017-09-21T15:52:00-06:00",
        "last_active": "2018-11-12T11:45:15-06:00",
        "created": "2017-04-27T07:23:44-06:00",
        "mobile_number": ""
      }
    },
    "time_off_request_notes": {
      "96024": {
        "id": 96024,
        "time_off_request_id": 1546922,
        "user_id": 423,
        "active": false,
        "note": "Taking a four day weekend to go on vacation.",
        "created": "2018-11-11T10:56:15-06:00",
        "last_modified": "2018-11-11T10:56:15-06:00"
      },
      "96132": {
        "id": 96132,
        "time_off_request_id": 1546922,
        "user_id": 423,
        "active": false,
        "note": "I will have Guy fill in on the show for Friday.",
        "created": "2018-11-12T09:13:44-06:00",
        "last_modified": "2018-11-12T09:13:44-06:00"
      }
    },
    "time_off_request_entries": {
      "11374": {
        "id": 11374,
        "time_off_request_id": 1546922,
        "status": "canceled",
        "approver_user_id": 417,
        "date": "2018-11-15",
        "entry_method": "manual",
        "duration": 28800,
        "start_time": "",
        "end_time": "",
        "jobcode_id": 1345687,
        "user_id": 423,
        "approved_timesheet_id": 0,
        "active": false,
        "created": "2018-11-11T10:56:15-06:00",
        "last_modified": "2018-11-11T10:56:15-06:00"
      },
      "11375": {
        "id": 11375,
        "time_off_request_id": 1546922,
        "status": "canceled",
        "approver_user_id": 417,
        "date": "2018-11-16",
        "entry_method": "manual",
        "duration": 28800,
        "start_time": "",
        "end_time": "",
        "jobcode_id": 1345687,
        "user_id": 423,
        "approved_timesheet_id": 0,
        "active": false,
        "created": "2018-11-11T10:56:15-06:00",
        "last_modified": "2018-11-11T10:56:15-06:00"
      }
    }
  }
}


Edit one or more time off requests.

HTTP Request

puthttps://rest.tsheets.com/api/v1/time_off_requests

Properties

Pass an array of Time Off Request objects as the value to a 'data' property (see example).

When editing a time off request you must uniquely identify it by passing in its id. All other properties defined on a Time Off Request object may be passed in to the request with a new value in order to change it. If the value passed in is the same as it was previously, or if a particular property is not passed in at all, it will be ignored.

Status Codes

Each time off request that is edited will come back with a _status_code and _status_message that will indicate whether the time off request was edited successfully. If there was a problem editing a time off request, there may also be an additional field, _status_extra, which will contain more details about the failure.

200 OK. Time off request was updated successfully.
403 Permission Denied. The requesting user did not have permission to edit the time off request for this user.
404 Not Found. Time off request either has never existed or has been deleted.
417 Expectation Failed. Something was wrong or missing with the properties supplied for this time off request. See the _status_extra value for more detail.

Time Off Request Entries

Time Off Request Entries are individual time off entries associated with a Time Off Request. Each entry will create a timesheet once the request is approved.

The Time Off Request Entry Object

Example

{
  "id": 11374,
  "time_off_request_id": 1546922,
  "status": "pending",
  "approver_user_id": 0,
  "date": "2018-11-15",
  "entry_method": "manual",
  "duration": 28800,
  "start_time": "2018-11-15T00:00:00-07:00",
  "end_time": "2018-11-15T23:59:59-07:00",
  "tz_string": "America/Denver",
  "jobcode_id": 1345687,
  "user_id": 423,
  "approved_timesheet_id": 0,
  "active": true,
  "created": "2018-11-11T10:56:15-06:00",
  "last_modified": "2018-11-11T10:56:15-06:00"
}

Following is a list of the properties that belong to a time off request entry, and a description of each.

id
read-only
Int Id of the time off request entry.
time_off_request_id
read-write
Int Id for the Time Off Request that this entry belongs to.
status
read-write
String One of: 'pending', 'approved', 'denied', or 'canceled'.
approver_user_id
read-only
Int User id of the user that approved or denied the time off request entry.
entry_method
read-write
String Either 'manual' or 'regular'. Manual time off request entries have a date and a duration (in seconds). Regular time off request entries have a start/end time (duration is calculated by TSheets) for determining availability in Schedule. Unique properties for each entry method type are below.
duration
read-write
Int The total number of seconds recorded for this time off request entry.
tz_string
read-only
String The timezone of the entry in string format.
jobcode_id
read-write
Int Jobcode id for the jobcode that this time off request entry is recorded against.
user_id
read-write
Int User id for the user that this time off request entry belongs to.
approved_timesheet_id
read-only
Int Id of the timesheet associated with this time off request entry when it is approved.
active
read-only
Boolean If true, this time off request entry is active. If false, this time off request entry is archived.
created
read-only
String Date/time when this time off request entry was created, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm).
last_modified
read-only
String Date/time when this time off request entry was last modified, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm).

Manual Entry Method

date
read-write
String The date the time off request entry is for (YYYY-MM-DD format).
start_time
read-only
String An ISO 8601 format (YYYY-MM-DDThh:mm:ss?hh:mm) date/time that represents the absolute start of a 24 hr period. E.g., 2019-06-17T00:00:00-06:00.
end_time
read-only
String An ISO 8601 format (YYYY-MM-DDThh:mm:ss?hh:mm) date/time that represents the absolute end of a 24 hr period. E.g., 2019-06-17T23:59:59-06:00.

Regular Entry Method

date
read-only
String The date the time off request entry is for (YYYY-MM-DD format).
start_time
read-write
String Date/time that represents the start time of this of this time off request entry, in ISO 8601 format (YYYY-MM-DDThh:mm:ss?hh:mm).
end_time
read-write
String Date/time that represents the end time of this of this time off request entry, in ISO 8601 format (YYYY-MM-DDThh:mm:ss?hh:mm).

Retrieve Time Off Request Entries

Example: Retrieve a list of all time off request entries for a time off request with a given id.

Request

curl "https://rest.tsheets.com/api/v1/time_off_request_entries?time_off_request_ids=1546922" \
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/time_off_request_entries?time_off_request_ids=1546922");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/time_off_request_entries?time_off_request_ids=1546922")
Dim request = New RestRequest(Method.[GET])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/time_off_request_entries?time_off_request_ids=1546922")
  .get()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/time_off_request_entries?time_off_request_ids=1546922",
  "method": "GET",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'GET',
  url: 'https://rest.tsheets.com/api/v1/time_off_request_entries',
  qs: {
    time_off_request_ids: '1546922',
  },
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/time_off_request_entries');
$request->setMethod(HTTP_METH_GET);

$request->setQueryData(array(
  'time_off_request_ids' => '1546922',
));

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/time_off_request_entries?time_off_request_ids=1546922")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/time_off_request_entries"

querystring = {
  "time_off_request_ids":"1546922",
}

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/time_off_request_entries?time_off_request_ids=1546922"

  req, _ := http.NewRequest("GET", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/time_off_request_entries?time_off_request_ids=1546922")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest, completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/time_off_request_entries?time_off_request_ids=1546922"; 

$client->GET($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "time_off_request_entries": {
      "11374": {
        "id": 11374,
        "time_off_request_id": 1546922,
        "status": "pending",
        "approver_user_id": 0,
        "date": "2018-11-15",
        "entry_method": "manual",
        "duration": 28800,
        "start_time": "2018-11-15T00:00:00-07:00",
        "end_time": "2018-11-15T23:59:59-07:00",
        "tz_string": "America/Denver",
        "jobcode_id": 1345687,
        "user_id": 423,
        "approved_timesheet_id": 0,
        "active": true,
        "created": "2018-11-11T10:56:15-06:00",
        "last_modified": "2018-11-11T10:56:15-06:00"
      },
      "11375": {
        "id": 11375,
        "time_off_request_id": 1546922,
        "status": "pending",
        "approver_user_id": 0,
        "date": "2018-11-16",
        "entry_method": "manual",
        "duration": 28800,
        "start_time": "2018-11-16T00:00:00-07:00",
        "end_time": "2018-11-16T23:59:59-07:00",
        "tz_string": "America/Denver",
        "jobcode_id": 1345687,
        "user_id": 423,
        "approved_timesheet_id": 0,
        "active": true,
        "created": "2018-11-11T10:56:15-06:00",
        "last_modified": "2018-11-11T10:56:15-06:00"
      }
    }
  },
  "more": false,
  "supplemental_data": {
    "time_off_requests": {
      "1546922": {
        "id": 1546922,
        "user_id": 423,
        "time_off_request_notes": [96024],
        "time_off_request_entries": [11374, 11375],
        "status": "pending",
        "active": true,
        "created": "2018-11-11T10:56:15-06:00",
        "last_modified": "2018-11-11T10:56:15-06:00"
      }
    },
    "jobcodes": {
      "1345687": {
        "id": 1345687,
        "parent_id": 0,
        "assigned_to_all": true,
        "billable": false,
        "active": true,
        "type": "pto",
        "has_children": false,
        "billable_rate": 0,
        "short_code": "vac",
        "name": "Vacation",
        "last_modified": "2013-07-24T19:05:53-06:00",
        "created": "2013-05-28T20:19:33-06:00"
      }
    },
    "users": {
      "423": {
       "id": 423,
       "first_name": "Sean",
       "last_name": "Evans",
       "group_id": 34,
       "active": true,
       "employee_number": 4,
       "salaried": false,
       "exempt": false,
       "username": "sevans",
       "email": "sevans@hotones.com",
       "payroll_id": 4,
       "hire_date": "2017-04-27",
       "term_date": "0000-00-00",
       "job_title": "",
       "gender": "",
       "last_modified": "2017-09-21T15:52:00-06:00",
       "last_active": "2018-11-12T11:45:15-06:00",
       "created": "2017-04-27T07:23:44-06:00",
       "mobile_number": ""
      }
    }
  }
}

Retrieves a list of time off request entries associated with your company, with filters to narrow down the results.

HTTP Request

gethttps://rest.tsheets.com/api/v1/time_off_request_entries

Filter Parameters

At least one of the following filters must be set.

ids
optional
Int Comma separated list of one or more time off request entry ids you'd like to filter on. Only time off request entries with an id set to one of these values will be returned.
time_off_request_ids
optional
Int Comma separated list of one or more Time Off Request ids you'd like to filter on. Only time off request entries associated with a time off request id set to one of these values will be returned.
approver_user_ids
optional
Int Comma separated list of one or more user ids. Only time off requests linked to one of these user ids will be returned. Only administrators or group managers may retrieve time off requests for users other than themselves. Furthermore, administrators or group managers may only retrieve time off requests for users that belong to their company.
status
optional
String One of: 'pending', 'approved', 'denied', or 'canceled'.
date
optional
String Only time off request entries set for this date will be returned (YYYY-MM-DD format).
start_time
optional
String Only time off request entries with a start_time greater than or equal to this Date/time will be returned, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm).
end_time
optional
String Only time off request entries with a start_time less than or equal to this Date/time will be returned, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm).
jobcode_ids
optional
Int Comma separated list of one or more jobcode ids you'd like to filter on. Only time off request entries with a jobcode id set to one of these values will be returned.
user_ids
optional
Int Comma separated list of one or more user ids. Only time off request entries linked to one of these user ids will be returned. Only administrators or group managers may retrieve time off request entries for users other than themselves. Furthermore, administrators or group managers may only retrieve time off request entries for users that belong to their company.
supplemental_data
optional
String 'yes' or 'no'. Default is 'yes'. Indicates whether supplemental data should be returned.
per_page
optional
Int Deprecated. Use limit for new code.
Represents how many results you'd like to retrieve per request. Default is 50. Max is 50.
If a value over 50 is provided, it is ignored, and the max is used.
limit
optional
Int Represents how many results you'd like to retrieve per request. Default is 200. Max is 200.
If present, this value must be: an integer, greater than zero, and not greater than 200.
Setting limit less than 1 or greater than 200 will result in an error.
page
optional
Int Represents the page of results you'd like to retrieve. Default is 1.

Create Time Off Request Entries

Example: Add a new time off request entry for a time off request.

Request Body

{
  "data": [{
    "time_off_request_id": 1546922,
    "date": "2018-11-16",
    "entry_method": "manual",
    "duration": 28800,
    "jobcode_id": 1345687
  }]
}


Request

curl -X POST \
  https://rest.tsheets.com/api/v1/time_off_request_entries \
  -H 'Authorization: Bearer <TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '<REQUEST BODY>'
var client = new RestClient("https://rest.tsheets.com/api/v1/time_off_request_entries");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <TOKEN>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "<REQUEST BODY>", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/time_off_request_entries")
Dim request = New RestRequest(Method.POST)
request.AddHeader("Authorization", "Bearer <TOKEN>")
request.AddHeader("Content-Type", "application/json")
request.AddParameter("application/json", "<REQUEST BODY>", ParameterType.RequestBody);
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<REQUEST BODY>");
Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/time_off_request_entries")
  .post(body)
  .addHeader("Authorization", "Bearer <TOKEN>")
  .addHeader("Content-Type", "application/json")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/time_off_request_entries?time_off_request_ids=1546922",
  "method": "POST",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
    "Content-Type", "application/json",
  },
  "processData": false,
  "data": "<REQUEST BODY>"
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'POST',
  url: 'https://rest.tsheets.com/api/v1/time_off_request_entries',
  headers: 
  { 
     'Authorization': 'Bearer <TOKEN>',
     'Content-Type': 'application/json',
  },
  body: '<REQUEST BODY>',
  json: true };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/time_off_request_entries');
$request->setMethod(HTTP_METH_POST);

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
  'Content-Type' => 'application/json',
));

$request->setBody('<REQUEST BODY>');

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/time_off_request_entries")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <TOKEN>',
request["Content-Type"] = 'application/json',
request.body = "<REQUEST BODY>"

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/time_off_request_entries"

payload = "<REQUEST BODY>"
headers = {
    'Authorization': 'Bearer <TOKEN>',
    'Content-Type': 'application/json',
    }

response = requests.request("POST", url, data=payload, headers=headers)

print(response.text)
package main

import (
  "fmt"
  "strings"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/time_off_request_entries"

  payload := strings.NewReader("<REQUEST BODY>")

  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, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))

}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
   "Content-Type": "application/json",
]
let parameters = <REQUEST BODY> as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/time_off_request_entries")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest,
  completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');
$client->addHeader('Content-Type', 'application/json');

$req = '<REQUEST BODY>';

$url="https://rest.tsheets.com/api/v1/time_off_request_entries"; 

$client->POST($url, $req);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "time_off_request_entries": {
      "11375": {
        "_status_code": 200,
        "_status_message": "Created",
        "id": 11375,
        "time_off_request_id": 1546922,
        "status": "pending",
        "approver_user_id": 0,
        "date": "2018-11-16",
        "entry_method": "manual",
        "duration": 28800,
        "start_time": "2018-11-16T00:00:00-07:00",
        "end_time": "2018-11-16T23:59:59-07:00",
        "tz_string": "America/Denver",
        "jobcode_id": 1345687,
        "user_id": 423,
        "approved_timesheet_id": 0,
        "active": true,
        "created": "2018-11-11T10:56:15-06:00",
        "last_modified": "2018-11-11T10:56:15-06:00"
      }
    }
  },
  "supplemental_data": {
    "time_off_requests": {
      "1546922": {
        "id": 1546922,
        "user_id": 423,
        "time_off_request_notes": [96024],
        "time_off_request_entries": [11374, 11375],
        "status": "pending",
        "active": true,
        "created": "2018-11-11T10:56:15-06:00",
        "last_modified": "2018-11-11T10:56:15-06:00"
      }
    },
    "jobcodes": {
      "1345687": {
        "id": 1345687,
        "parent_id": 0,
        "assigned_to_all": true,
        "billable": false,
        "active": true,
        "type": "pto",
        "has_children": false,
        "billable_rate": 0,
        "short_code": "vac",
        "name": "Vacation",
        "last_modified": "2013-07-24T19:05:53-06:00",
        "created": "2013-05-28T20:19:33-06:00"
      }
    },
    "users": {
      "423": {
       "id": 423,
       "first_name": "Sean",
       "last_name": "Evans",
       "group_id": 34,
       "active": true,
       "employee_number": 4,
       "salaried": false,
       "exempt": false,
       "username": "sevans",
       "email": "sevans@hotones.com",
       "payroll_id": 4,
       "hire_date": "2017-04-27",
       "term_date": "0000-00-00",
       "job_title": "",
       "gender": "",
       "last_modified": "2017-09-21T15:52:00-06:00",
       "last_active": "2018-11-12T11:45:15-06:00",
       "created": "2017-04-27T07:23:44-06:00",
       "mobile_number": ""
      }
    }
  }
}

Example: Add a new time off request entry for a time off request, given a specific time range.

Request Body

{
  "data": [{
    "time_off_request_id": 1546922,
    "entry_method": "regular",
    "duration": 14400,
    "start_time": "2018-11-16T08:00:00-06:00",
    "end_time": "2018-11-16T12:00:00-06:00",
    "jobcode_id": 1345687
  }]
}


Request

curl -X POST \
  https://rest.tsheets.com/api/v1/time_off_request_entries \
  -H 'Authorization: Bearer <TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '<REQUEST BODY>'
var client = new RestClient("https://rest.tsheets.com/api/v1/time_off_request_entries");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <TOKEN>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "<REQUEST BODY>", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/time_off_request_entries")
Dim request = New RestRequest(Method.POST)
request.AddHeader("Authorization", "Bearer <TOKEN>")
request.AddHeader("Content-Type", "application/json")
request.AddParameter("application/json", "<REQUEST BODY>", ParameterType.RequestBody);
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<REQUEST BODY>");
Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/time_off_request_entries")
  .post(body)
  .addHeader("Authorization", "Bearer <TOKEN>")
  .addHeader("Content-Type", "application/json")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/time_off_request_entries?time_off_request_ids=1546922",
  "method": "POST",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
    "Content-Type", "application/json",
  },
  "processData": false,
  "data": "<REQUEST BODY>"
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'POST',
  url: 'https://rest.tsheets.com/api/v1/time_off_request_entries',
  headers: 
  { 
     'Authorization': 'Bearer <TOKEN>',
     'Content-Type': 'application/json',
  },
  body: '<REQUEST BODY>',
  json: true };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/time_off_request_entries');
$request->setMethod(HTTP_METH_POST);

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
  'Content-Type' => 'application/json',
));

$request->setBody('<REQUEST BODY>');

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/time_off_request_entries")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <TOKEN>',
request["Content-Type"] = 'application/json',
request.body = "<REQUEST BODY>"

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/time_off_request_entries"

payload = "<REQUEST BODY>"
headers = {
    'Authorization': 'Bearer <TOKEN>',
    'Content-Type': 'application/json',
    }

response = requests.request("POST", url, data=payload, headers=headers)

print(response.text)
package main

import (
  "fmt"
  "strings"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/time_off_request_entries"

  payload := strings.NewReader("<REQUEST BODY>")

  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, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))

}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
   "Content-Type": "application/json",
]
let parameters = <REQUEST BODY> as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/time_off_request_entries")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest,
  completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');
$client->addHeader('Content-Type', 'application/json');

$req = '<REQUEST BODY>';

$url="https://rest.tsheets.com/api/v1/time_off_request_entries"; 

$client->POST($url, $req);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "time_off_request_entries": {
      "11375": {
        "_status_code": 200,
        "_status_message": "Created",
        "id": 11375,
        "time_off_request_id": 1546922,
        "status": "pending",
        "approver_user_id": 0,
        "date": "2018-11-16",
        "entry_method": "regular",
        "duration": 14400,
        "start_time": "2018-11-16T08:00:00-06:00",
        "end_time": "2018-11-16T12:00:00-06:00",
        "jobcode_id": 1345687,
        "user_id": 423,
        "approved_timesheet_id": 0,
        "active": true,
        "created": "2018-11-11T10:56:15-06:00",
        "last_modified": "2018-11-11T10:56:15-06:00"
      }
    }
  },
  "supplemental_data": {
    "time_off_requests": {
      "1546922": {
        "id": 1546922,
        "user_id": 423,
        "time_off_request_notes": [96024],
        "time_off_request_entries": [11374, 11375],
        "status": "pending",
        "active": true,
        "created": "2018-11-11T10:56:15-06:00",
        "last_modified": "2018-11-11T10:56:15-06:00"
      }
    },
    "jobcodes": {
      "1345687": {
        "id": 1345687,
        "parent_id": 0,
        "assigned_to_all": true,
        "billable": false,
        "active": true,
        "type": "pto",
        "has_children": false,
        "billable_rate": 0,
        "short_code": "vac",
        "name": "Vacation",
        "last_modified": "2013-07-24T19:05:53-06:00",
        "created": "2013-05-28T20:19:33-06:00"
      }
    },
    "users": {
      "423": {
       "id": 423,
       "first_name": "Sean",
       "last_name": "Evans",
       "group_id": 34,
       "active": true,
       "employee_number": 4,
       "salaried": false,
       "exempt": false,
       "username": "sevans",
       "email": "sevans@hotones.com",
       "payroll_id": 4,
       "hire_date": "2017-04-27",
       "term_date": "0000-00-00",
       "job_title": "",
       "gender": "",
       "last_modified": "2017-09-21T15:52:00-06:00",
       "last_active": "2018-11-12T11:45:15-06:00",
       "created": "2017-04-27T07:23:44-06:00",
       "mobile_number": ""
      }
    }
  }
}

Add one or more time off request entries.

HTTP Request

posthttps://rest.tsheets.com/api/v1/time_off_request_entries

Properties

Pass an array of Time Off Request Entry objects as the value to a 'data' property (see example).

time_off_request_id
required
Int Id for the Time Off Request that this entry will belong to. The Time Off Request this entry is assigned to will determine the user assigned to this time off request entry. Only administrators or group managers may add time off request entries for users other than themselves. Furthermore, administrators or group managers may only add time off request entries for users that belong to their company.
status
optional
String One of: 'pending', 'approved', 'denied', or 'canceled'.
entry_method
required
String Either 'manual' or 'regular'. Manual time off request entries have a date and a duration (in seconds). Regular time off request entries have a start/end time for determining availability in Schedule.
duration
required
Int The total number of seconds recorded for this time off request entry.
jobcode_id
required
Int Jobcode id for the jobcode that this time off request entry is recorded against.
date
required (manual method only)
String The date the time off request entry is for (YYYY-MM-DD format).
start_time
required (regular method only)
String Date/time that represents the start time of this of this time off request entry, in ISO 8601 format (YYYY-MM-DDThh:mm:ss?hh:mm).
end_time
required (regular method only)
String Date/time that represents the end time of this of this time off request entry, in ISO 8601 format (YYYY-MM-DDThh:mm:ss?hh:mm).

Status Codes

Each time off request entry that is created will come back with a _status_code and _status_message that will indicate whether the time off request entry was created successfully. If there was a problem creating a time off request entry, there may also be an additional field, _status_extra, which will contain more details about the failure.

200 OK. Time off request entry was created successfully.
403 Permission Denied. The requesting user does not have permission to create the time off request entry for this user.
417 Expectation Failed. Something was wrong or missing with the properties supplied for this time off request entry. See the _status_extra value for more detail.

Update Time Off Request Entries

Example: Change the duration of a time off request entry to four hours.

Request Body

{
  "data": [{
    "id": 11374,
    "duration": 14400
  }]
}

Request

curl -X PUT \
  https://rest.tsheets.com/api/v1/time_off_request_entries \
  -H 'Authorization: Bearer <TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '<REQUEST BODY>'
var client = new RestClient("https://rest.tsheets.com/api/v1/time_off_request_entries");
var request = new RestRequest(Method.PUT);
request.AddHeader("Authorization", "Bearer <TOKEN>");
request.AddHeader("Content-Type", "application/json");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/time_off_request_entries")
Dim request = New RestRequest(Method.PUT)
request.AddHeader("Authorization", "Bearer <TOKEN>")
request.AddHeader("Content-Type", "application/json")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<REQUEST BODY>");
Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/time_off_request_entries")
  .put(body)
  .addHeader("Authorization", "Bearer <TOKEN>")
  .addHeader("Content-Type", "application/json")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/time_off_request_entries?time_off_request_ids=1546922",
  "method": "PUT",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
    "Content-Type", "application/json",
  },
  "processData": false,
  "data": "<REQUEST BODY>"
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'PUT',
  url: 'https://rest.tsheets.com/api/v1/time_off_request_entries',
  headers: 
  { 
     'Authorization': 'Bearer <TOKEN>',
     'Content-Type': 'application/json',
  },
  body: '<REQUEST BODY>',
  json: true };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/time_off_request_entries');
$request->setMethod(HTTP_METH_PUT);

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
  'Content-Type' => 'application/json',
));

$request->setBody('<REQUEST BODY>');

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/time_off_request_entries")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <TOKEN>',
request["Content-Type"] = 'application/json',
request.body = "<REQUEST BODY>"

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/time_off_request_entries"

payload = "<REQUEST BODY>"
headers = {
    'Authorization': 'Bearer <TOKEN>',
    'Content-Type': 'application/json',
    }

response = requests.request("PUT", url, data=payload, headers=headers)

print(response.text)
package main

import (
  "fmt"
  "strings"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/time_off_request_entries"

  payload := strings.NewReader("<REQUEST BODY>")

  req, _ := http.NewRequest("PUT", 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, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))

}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
   "Content-Type": "application/json",
]
let parameters = <REQUEST BODY> as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(
  url: NSURL(string: "http://rest.tsheets.com/api/v1/time_off_request_entries")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "PUT"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest,
  completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');
$client->addHeader('Content-Type', 'application/json');

$req = '<REQUEST BODY>';

$url="http://rest.tsheets.com/api/v1/time_off_request_entries"; 

$client->PUT($url, $req);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "time_off_request_entries": {
      "11374": {
        "_status_code": 200,
        "_status_message": "Updated",
        "id": 11374,
        "time_off_request_id": 1546922,
        "status": "pending",
        "approver_user_id": 0,
        "date": "2018-11-15",
        "entry_method": "manual",
        "duration": 14400,
        "start_time": "2018-11-16T00:00:00-07:00",
        "end_time": "2018-11-16T23:59:59-07:00",
        "tz_string": "America/Denver",
        "jobcode_id": 1345687,
        "user_id": 423,
        "approved_timesheet_id": 0,
        "active": true,
        "created": "2018-11-11T10:56:15-06:00",
        "last_modified": "2018-11-11T10:56:15-06:00"
      }
    }
  },
  "supplemental_data": {
    "time_off_requests": {
      "1546922": {
        "id": 1546922,
        "user_id": 423,
        "time_off_request_notes": [96024],
        "time_off_request_entries": [11374, 11375],
        "status": "pending",
        "active": true,
        "created": "2018-11-11T10:56:15-06:00",
        "last_modified": "2018-11-11T10:56:15-06:00"
      }
    },
    "jobcodes": {
      "1345687": {
        "id": 1345687,
        "parent_id": 0,
        "assigned_to_all": true,
        "billable": false,
        "active": true,
        "type": "pto",
        "has_children": false,
        "billable_rate": 0,
        "short_code": "vac",
        "name": "Vacation",
        "last_modified": "2013-07-24T19:05:53-06:00",
        "created": "2013-05-28T20:19:33-06:00"
      }
    },
    "users": {
      "423": {
       "id": 423,
       "first_name": "Sean",
       "last_name": "Evans",
       "group_id": 34,
       "active": true,
       "employee_number": 4,
       "salaried": false,
       "exempt": false,
       "username": "sevans",
       "email": "sevans@hotones.com",
       "payroll_id": 4,
       "hire_date": "2017-04-27",
       "term_date": "0000-00-00",
       "job_title": "",
       "gender": "",
       "last_modified": "2017-09-21T15:52:00-06:00",
       "last_active": "2018-11-12T11:45:15-06:00",
       "created": "2017-04-27T07:23:44-06:00",
       "mobile_number": ""
      }
    }
  }
}


Example: Archive a time off request entry.

Request Body

{
  "data": [{
    "id": 11374,
    "active": false
  }]
}

Request

curl -X PUT \
  https://rest.tsheets.com/api/v1/time_off_request_entries \
  -H 'Authorization: Bearer <TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '<REQUEST BODY>'
var client = new RestClient("https://rest.tsheets.com/api/v1/time_off_request_entries");
var request = new RestRequest(Method.PUT);
request.AddHeader("Authorization", "Bearer <TOKEN>");
request.AddHeader("Content-Type", "application/json");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/time_off_request_entries")
Dim request = New RestRequest(Method.PUT)
request.AddHeader("Authorization", "Bearer <TOKEN>")
request.AddHeader("Content-Type", "application/json")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<REQUEST BODY>");
Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/time_off_request_entries")
  .put(body)
  .addHeader("Authorization", "Bearer <TOKEN>")
  .addHeader("Content-Type", "application/json")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/time_off_request_entries?time_off_request_ids=1546922",
  "method": "PUT",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
    "Content-Type", "application/json",
  },
  "processData": false,
  "data": "<REQUEST BODY>"
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'PUT',
  url: 'https://rest.tsheets.com/api/v1/time_off_request_entries',
  headers: 
  { 
     'Authorization': 'Bearer <TOKEN>',
     'Content-Type': 'application/json',
  },
  body: '<REQUEST BODY>',
  json: true };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/time_off_request_entries');
$request->setMethod(HTTP_METH_PUT);

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
  'Content-Type' => 'application/json',
));

$request->setBody('<REQUEST BODY>');

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/time_off_request_entries")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <TOKEN>',
request["Content-Type"] = 'application/json',
request.body = "<REQUEST BODY>"

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/time_off_request_entries"

payload = "<REQUEST BODY>"
headers = {
    'Authorization': 'Bearer <TOKEN>',
    'Content-Type': 'application/json',
    }

response = requests.request("PUT", url, data=payload, headers=headers)

print(response.text)
package main

import (
  "fmt"
  "strings"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/time_off_request_entries"

  payload := strings.NewReader("<REQUEST BODY>")

  req, _ := http.NewRequest("PUT", 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, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))

}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
   "Content-Type": "application/json",
]
let parameters = <REQUEST BODY> as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(
  url: NSURL(string: "http://rest.tsheets.com/api/v1/time_off_request_entries")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "PUT"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest,
  completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');
$client->addHeader('Content-Type', 'application/json');

$req = '<REQUEST BODY>';

$url="http://rest.tsheets.com/api/v1/time_off_request_entries"; 

$client->PUT($url, $req);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "time_off_request_entries": {
      "11374": {
        "_status_code": 200,
        "_status_message": "Updated",
        "id": 11374,
        "time_off_request_id": 1546922,
        "status": "canceled",
        "approver_user_id": 417,
        "date": "2018-11-15",
        "entry_method": "manual",
        "duration": 14400,
        "start_time": "2018-11-16T00:00:00-07:00",
        "end_time": "2018-11-16T23:59:59-07:00",
        "tz_string": "America/Denver",
        "jobcode_id": 1345687,
        "user_id": 423,
        "approved_timesheet_id": 0,
        "active": false,
        "created": "2018-11-11T10:56:15-06:00",
        "last_modified": "2018-11-11T10:56:15-06:00"
      }
    }
  },
  "supplemental_data": {
    "time_off_requests": {
      "1546922": {
        "id": 1546922,
        "user_id": 423,
        "time_off_request_notes": [96024],
        "time_off_request_entries": [11375],
        "status": "approved",
        "active": true,
        "created": "2018-11-11T10:56:15-06:00",
        "last_modified": "2018-11-11T10:56:15-06:00"
      }
    },
    "jobcodes": {
      "1345687": {
        "id": 1345687,
        "parent_id": 0,
        "assigned_to_all": true,
        "billable": false,
        "active": true,
        "type": "pto",
        "has_children": false,
        "billable_rate": 0,
        "short_code": "vac",
        "name": "Vacation",
        "last_modified": "2013-07-24T19:05:53-06:00",
        "created": "2013-05-28T20:19:33-06:00"
      }
    },
    "users": {
      "417": {
        "id": 417,
        "first_name": "Adam",
        "last_name": "Manager",
        "group_id": 34,
        "active": true,
        "employee_number": 2,
        "salaried": false,
        "exempt": false,
        "username": "amanager",
        "email": "amanager@hotones.com",
        "payroll_id": 2,
        "hire_date": "2017-01-06",
        "term_date": "0000-00-00",
        "job_title": "",
        "gender": "",
        "last_modified": "2017-08-16T09:14:02-06:00",
        "last_active": "2018-11-12T15:23:22-06:00",
        "created": "2017-01-06T10:09:12-06:00",
        "mobile_number": ""
       },
      "423": {
       "id": 423,
       "first_name": "Sean",
       "last_name": "Evans",
       "group_id": 34,
       "active": true,
       "employee_number": 4,
       "salaried": false,
       "exempt": false,
       "username": "sevans",
       "email": "sevans@hotones.com",
       "payroll_id": 4,
       "hire_date": "2017-04-27",
       "term_date": "0000-00-00",
       "job_title": "",
       "gender": "",
       "last_modified": "2017-09-21T15:52:00-06:00",
       "last_active": "2018-11-12T11:45:15-06:00",
       "created": "2017-04-27T07:23:44-06:00",
       "mobile_number": ""
      }
    }
  }
}


Edit one or more time off request entries.

HTTP Request

puthttps://rest.tsheets.com/api/v1/time_off_request_entries

Properties

Pass an array of Time Off Request Entry objects as the value to a 'data' property (see example).

When editing a time off request entry you must uniquely identify it by passing in its id. All other properties defined on a Time Off Request Entry object may be passed in to the request with a new value in order to change it. If the value passed in is the same as it was previously, or if a particular property is not passed in at all, it will be ignored.

Status Codes

Each time off request entry that is edited will come back with a _status_code and _status_message that will indicate whether the time off request entry was edited successfully. If there was a problem editing the time off request entry, there may also be an additional field, _status_extra, which will contain more details about the failure.

200 OK. Time off request entry updated successfully.
403 Permission Denied. The requesting user did not have permission to edit the time off request entry for this user.
404 Not Found. Time off request entry either has never existed or has been deleted.
417 Expectation Failed. Something was wrong or missing with the properties supplied for this time off request entry. See the _status_extra value for more detail.

Users

The User Object

Example

{
  "id": 933849,
  "first_name": "Mary",
  "last_name": "Samsonite",
  "group_id": 0,
  "active": true,
  "employee_number": 0,
  "salaried": false,
  "exempt": false,
  "username": "admin",
  "email": "admin@example.com",
  "email_verified": false,
  "payroll_id": "",
  "mobile_number": "2087231456",
  "hire_date": "0000-00-00",
  "term_date": "0000-00-00",
  "last_modified": "2018-03-28T17:24:20+00:00",
  "last_active": "",
  "created": "2018-03-27T16:13:34+00:00",
  "client_url": "api_sample_output",
  "company_name": "API Sample Output Company",
  "profile_image_url": "https:\/\/www.gravatar.com\/avatar\/e64c7d89f26bd1972efa854d13d7dd61",
  "display_name": "",
  "pto_balances": {
    "2624351": 0,
    "2624353": 0,
    "2624355": 0
  },
  "submitted_to": "2000-01-01",
  "approved_to": "2000-01-01",
  "manager_of_group_ids": [

  ],
  "require_password_change": false,
  "pay_rate": 0,
  "pay_interval": "hour",
  "permissions": {
    "admin": true,
    "mobile": true,
    "status_box": false,
    "reports": false,
    "manage_timesheets": false,
    "manage_authorization": false,
    "manage_users": false,
    "manage_my_timesheets": false,
    "manage_jobcodes": false,
    "pin_login": false,
    "approve_timesheets": false,
    "manage_schedules": false,
    "external_access": false,
    "manage_my_schedule": false,
    "manage_company_schedules": false,
    "view_company_schedules": false,
    "view_group_schedules": false,
    "manage_no_schedules": false,
    "view_my_schedules": false,
    "time_tracking": false
  },
  "customfields": ""
}

Following is a list of the properties that belong to a user object, and a description of each.

id
read-only
Int Id of this user.
first_name
read-write
String First name of user.
last_name
read-write
String Last name of user.
display_name
read-write
String The display name of user. NOTE: field will always be empty string unless feature GED_INCLUSION is enabled (contact support for more info), if feature is enabled then value will be a non-null display_name value (users who have not setup their display_name will return '')
group_id
read-write
Int Id of the group this user belongs to.
active
read-write
Boolean true or false. If false, this user is considered archived.
employee_number
read-write
Int Unique number associated with this user. For your reference only.
salaried
read-write
Boolean true or false. Indicates whether or not the user is salaried.
exempt
read-write
Boolean true or false Indicates e.g. whether or not the user is eligible for overtime pay.
username
read-write
String Username associated with this user.
email
read-write
String Email address associated with this user.
email_verified
read-only
Boolean true or false. Indicates whether or not the email address has been confirmed by the user.
payroll_id
read-write
String Unique company wide string associated with this user. Usually used for linking with external systems.
hire_date
read-write
String Date on which this user was hired (YYYY-MM-DD format).
term_date
read-write
String Date on which this user was terminated (YYYY-MM-DD format).
last_modified
read-only
String Date/time when this user was last modified, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm).
last_active
read-only
String Date/time when this user last performed any action, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm).
created
read-only
String Date/time when this user was created, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm).
client_url
read-only
String Client account url identifier associated with this user.
company_name
read-only
String Client account name identifier associated with the user.
profile_image_url
read-only
String Url identifier associated with this user's profile image.
mobile_number
read-write
String Mobile phone number associated with this user.
pto_balances
read-only
Object List of jobcode identifiers and their respective PTO balances for this user (in seconds). Jobcode information for PTO Jobcodes will be supplied in supplemental_data.
submitted_to
read-write
String The latest date this user has submitted timesheets up to (YYYY-MM-DD format).

Note: requires the Approvals Add-On to be installed.

Note: this property is read-only unless the account setting approvals->settings->employee_approval = 1. See Effective Settings documentation for details.
approved_to
read-write
String The latest date this user has had timesheets approved to (YYYY-MM-DD format).

Note: requires the Approvals Add-On to be installed.

Note: When updating this value, if the value is greater than the submitted_to date for this user, both properties will be updated. This is the equivalent of a manager/admin submitting time on a user's behalf.
manager_of_group_ids
read-only
Int[] The group ids that this user manages.
require_password_change
read-write
Boolean If true, this user will be required to change their password on their next login.
password
write-only
String May only be set when editing the currently authenticated user (i.e. you may only edit your own password).
login_pin
write-only
Int Used for logging into a Kiosk or similar.
pay_rate
read-only
Float The rate of pay associated with this user. Only visible to admins.
pay_interval
read-only
String The timeframe to which this user's pay rate applies, either 'hour' or 'year'. Only visible to admins.
permissions
read-write
Object The permission settings that apply to this user.
customfields
read-write
JSON Object A key/value map of customfield ids to the customfield items that are associated with the user.

Note: this property is present only if the Custom Fields Add-On is installed.

User Permissions

The rights assignable to an individual user. All properties are read-write, and of type Boolean.

Permission Default Description
admin false Administrator, can perform any changes on the account.
mobile true Allowed to use mobile devices to record time.
status_box false Able to view the list of users currently working for the company.
reports false Able to run/view all reports for the company.
manage_timesheets false Able to create/edit/delete timesheets for anyone in the company.
manage_authorization false Able to manage computer authorization for the company.
manage_users false Able to create/edit/delete users, groups, and managers for the entire company.
manage_my_timesheets false Able to completely manage own timesheets.
manage_jobcodes false Able to create/edit/delete jobcodes and custom field items for the entire company.
pin_login false Able to login to apps via PIN.
approve_timesheets false Able to run approval reports and approve time for all employees.
manage_schedules false Able to create/edit/delete events within the schedule for the groups that the user can manage.
manage_my_schedule false Able to create/edit/delete events within the schedule for only themselves.
manage_company_schedules false Able to create/edit/delete events within the schedule for any user in the company.
manage_no_schedule false Not able to create/edit/delete events within the schedule for any user.
view_company_schedules false Able to view published events within the schedule for any user in the company.
view_group_schedules false Able to view published events within the schedule for the groups that the user is a member of.
view_my_schedules false Able to view published events within the schedule for themselves.
time_tracking false Able to track time and have time tracked on their behalf.

Retrieve Users

Example: Retrieve a list of all active users.

Request

curl "https://rest.tsheets.com/api/v1/users" \
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/users");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/users")
Dim request = New RestRequest(Method.[GET])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/users")
  .get()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/users",
  "method": "GET",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'GET',
  url: 'https://rest.tsheets.com/api/v1/users',
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/users');
$request->setMethod(HTTP_METH_GET);

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/users")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/users"

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/users"

  req, _ := http.NewRequest("GET", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/users")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest, completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/users"; 

$client->GET($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Example: Retrieve a list of all users (active or deleted) whose last name starts with 'sm'. Set pagination to 30 results/page.

Request

curl "https://rest.tsheets.com/api/v1/users?limit=30&last_name=sm*" \
  -H "Authorization: Bearer <TOKEN>" \
var client = new RestClient("https://rest.tsheets.com/api/v1/users?limit=30&last_name=sm*");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <TOKEN>");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/users?limit=30&last_name=sm*")
Dim request = New RestRequest(Method.[GET])
request.AddHeader("Authorization", "Bearer <TOKEN>")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/users?limit=30&last_name=sm*")
  .get()
  .addHeader("Authorization", "Bearer <TOKEN>")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/users?limit=30&last_name=sm*",
  "method": "GET",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
  }
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'GET',
  url: 'https://rest.tsheets.com/api/v1/users',
  qs: {
    limit: '30',
    last_name: 'sm*',
  },
  headers: 
   {
     'Authorization': 'Bearer <TOKEN>',
   } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/users');
$request->setMethod(HTTP_METH_GET);

$request->setQueryData(array(
  'limit' => '30',
  'last_name' => 'sm*',
));

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/users?limit=30&last_name=sm*")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <TOKEN>',

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/users"

querystring = {
  "limit":"30",
  "last_name":"sm*",
}

payload = ""
headers = {
   'Authorization': "Bearer <TOKEN>",
  }

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)
package main

import (
  "fmt"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/users?limit=30&last_name=sm*"

  req, _ := http.NewRequest("GET", url, nil)

  req.Header.Add("Authorization", "Bearer <TOKEN>")

  res, _ := http.DefaultClient.Do(req)

  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))
}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
]

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/users?limit=30&last_name=sm*")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest, completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');

$url="https://rest.tsheets.com/api/v1/users?limit=30&last_name=sm*"; 

$client->GET($url);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "users": {
      "933849": {
        "id": 933849,
        "first_name": "Mary",
        "last_name": "Samsonite",
        "group_id": 0,
        "active": true,
        "employee_number": 0,
        "salaried": false,
        "exempt": false,
        "username": "admin",
        "email": "admin@example.com",
        "email_verified": false,
        "payroll_id": "",
        "mobile_number": "2087231456",
        "hire_date": "0000-00-00",
        "term_date": "0000-00-00",
        "last_modified": "2018-03-28T17:24:20+00:00",
        "last_active": "",
        "created": "2018-03-27T16:13:34+00:00",
        "client_url": "api_sample_output",
        "company_name": "API Sample Output Company",
        "profile_image_url": "https:\/\/www.gravatar.com\/avatar\/e64c7d89f26bd1972efa854d13d7dd61",
        "display_name": "",
        "pto_balances": {
          "2624351": 0,
          "2624353": 0,
          "2624355": 0
        },
        "submitted_to": "2000-01-01",
        "approved_to": "2000-01-01",
        "manager_of_group_ids": [ ],
        "require_password_change": false,
        "pay_rate": 0,
        "pay_interval": "hour",
        "permissions": {
          "admin": true,
          "mobile": true,
          "status_box": false,
          "reports": false,
          "manage_timesheets": false,
          "manage_authorization": false,
          "manage_users": false,
          "manage_my_timesheets": false,
          "manage_jobcodes": false,
          "pin_login": false,
          "approve_timesheets": false,
          "manage_schedules": false,
          "external_access": false,
          "manage_my_schedule": false,
          "manage_company_schedules": false,
          "view_company_schedules": false,
          "view_group_schedules": false,
          "manage_no_schedules": false,
          "view_my_schedules": false,
          "time_tracking": false
        },
        "customfields": ""
      },
      "933845": {
        "id": 933845,
        "first_name": "Bob",
        "last_name": "Smith",
        "group_id": 64965,
        "active": true,
        "employee_number": 0,
        "salaried": false,
        "exempt": false,
        "username": "bobsmith",
        "email": "",
        "email_verified": false,
        "payroll_id": "",
        "hire_date": "0000-00-00",
        "term_date": "0000-00-00",
        "last_modified": "2018-03-27T16:13:33+00:00",
        "last_active": "2018-03-28T20:16:39+00:00",
        "created": "2018-03-27T16:13:33+00:00",
        "client_url": "api_sample_output",
        "company_name": "API Sample Output Company",
        "profile_image_url": "",
        "display_name": "",
        "mobile_number": "",
        "pto_balances": {
          "2624351": 0,
          "2624353": 0,
          "2624355": 0
        },
        "submitted_to": "2000-01-01",
        "approved_to": "2000-01-01",
        "manager_of_group_ids": [ ],
        "require_password_change": false,
        "pay_rate": 0,
        "pay_interval": "hour",
        "permissions": {
          "admin": false,
          "mobile": true,
          "status_box": false,
          "reports": false,
          "manage_timesheets": false,
          "manage_authorization": false,
          "manage_users": false,
          "manage_my_timesheets": false,
          "manage_jobcodes": false,
          "pin_login": false,
          "approve_timesheets": false,
          "manage_schedules": false,
          "external_access": false,
          "manage_my_schedule": false,
          "manage_company_schedules": false,
          "view_company_schedules": false,
          "view_group_schedules": false,
          "manage_no_schedules": false,
          "view_my_schedules": false,
          "time_tracking": false
        },
        "customfields": ""
      }
    }
  },
  "more": false,
  "supplemental_data": {
    "jobcodes": {
      "2624351": {
        "id": 2624351,
        "parent_id": 0,
        "assigned_to_all": true,
        "billable": false,
        "active": true,
        "type": "pto",
        "has_children": false,
        "billable_rate": 0,
        "short_code": "",
        "name": "Sick",
        "last_modified": "2018-03-27T16:13:28+00:00",
        "created": "2018-03-27T16:13:28+00:00",
        "filtered_customfielditems": "",
        "required_customfields": [ ],
        "locations": [ ]
      },
      "2624353": {
        "id": 2624353,
        "parent_id": 0,
        "assigned_to_all": true,
        "billable": false,
        "active": true,
        "type": "pto",
        "has_children": false,
        "billable_rate": 0,
        "short_code": "",
        "name": "Vacation",
        "last_modified": "2018-03-27T16:13:28+00:00",
        "created": "2018-03-27T16:13:28+00:00",
        "filtered_customfielditems": "",
        "required_customfields": [ ],
        "locations": [ ]
      },
      "2624355": {
        "id": 2624355,
        "parent_id": 0,
        "assigned_to_all": true,
        "billable": false,
        "active": true,
        "type": "pto",
        "has_children": false,
        "billable_rate": 0,
        "short_code": "",
        "name": "Holiday",
        "last_modified": "2018-03-27T16:13:28+00:00",
        "created": "2018-03-27T16:13:28+00:00",
        "filtered_customfielditems": "",
        "required_customfields": [ ],
        "locations": [ ]
      }
    },
    "groups": {
      "64965": {
        "id": 64965,
        "active": true,
        "name": "Construction",
        "last_modified": "2018-03-27T16:13:30+00:00",
        "created": "2018-03-27T16:13:29+00:00",
        "manager_ids": [
          "933833"
        ]
      }
    }
  }
}

Retrieves a list of all users associated with your company, with optional filters to narrow down the results.

HTTP Request

gethttps://rest.tsheets.com/api/v1/users

Filter Parameters

ids
optional
Int Comma separated list of one or more user ids you'd like to filter on.
not_ids
optional
Int Comma separated list of one or more user ids you'd like to filter on. Specifically, the user ids you'd like to exclude.
employee_numbers
optional
Int Comma separated list of one or more employee numbers you'd like to filter on.
usernames
optional
String Comma separated list of one or more usernames you'd like to filter on.
group_ids
optional
Int Comma separated list of one or more group ids you'd like to filter on.
not_group_ids
optional
Int Comma separated list of one or more group ids you'd like to filter on. Specifically, the group ids you'd like to exclude.
payroll_ids
optional
String A comma-separated string of payroll ids. Only users with these payroll ids will be returned.
active
optional
String 'yes', 'no', or 'both'. Default is 'yes'.
first_name
optional
String * will be interpreted as a wild card. Starts matching from the beginning of the string.
last_name
optional
String * will be interpreted as a wild card. Starts matching from the beginning of the string.
modified_before
optional
String Only users modified before this date/time will be returned, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm).
modified_since
optional
String Only users modified since this date/time will be returned, in ISO 8601 format (YYYY-MM-DDThh:mm:ss±hh:mm).
supplemental_data
optional
String 'yes' or 'no'. Default is 'yes'. Indicates whether supplemental data should be returned.
per_page
optional
Int Deprecated. Use limit for new code.
Represents how many results you'd like to retrieve per request. Default is 50. Max is 50.
If a value over 50 is provided, it is ignored, and the max is used.
limit
optional
Int Represents how many results you'd like to retrieve per request. Default is 200. Max is 200.
If present, this value must be: an integer, greater than zero, and not greater than 200.
Setting limit less than 1 or greater than 200 will result in an error.
page
optional
Int Represents the page of results you'd like to retrieve. Default is 1.

Create Users

Example: Create two new users.

Request Body

 {
  "data":
  [ 
    {
      "username": "joni",
      "first_name": "Joni",
      "last_name": "Smith",
      "email": "jsmith@example.com"
    },
    {
      "username": "frank",
      "first_name": "Frank",
      "last_name": "Church",
      "mobile_number": "2018675309"
    }
  ]
}

Request

curl -X POST \
  https://rest.tsheets.com/api/v1/users \
  -H 'Authorization: Bearer <TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '<REQUEST BODY>'
var client = new RestClient("https://rest.tsheets.com/api/v1/users");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <TOKEN>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "<REQUEST BODY>", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/users")
Dim request = New RestRequest(Method.POST)
request.AddHeader("Authorization", "Bearer <TOKEN>")
request.AddHeader("Content-Type", "application/json")
request.AddParameter("application/json", "<REQUEST BODY>", ParameterType.RequestBody);
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<REQUEST BODY>");
Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/users")
  .post(body)
  .addHeader("Authorization", "Bearer <TOKEN>")
  .addHeader("Content-Type", "application/json")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/users?limit=30&last_name=sm*",
  "method": "POST",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
    "Content-Type", "application/json",
  },
  "processData": false,
  "data": "<REQUEST BODY>"
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'POST',
  url: 'https://rest.tsheets.com/api/v1/users',
  headers: 
  { 
     'Authorization': 'Bearer <TOKEN>',
     'Content-Type': 'application/json',
  },
  body: '<REQUEST BODY>',
  json: true };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/users');
$request->setMethod(HTTP_METH_POST);

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
  'Content-Type' => 'application/json',
));

$request->setBody('<REQUEST BODY>');

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/users")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <TOKEN>',
request["Content-Type"] = 'application/json',
request.body = "<REQUEST BODY>"

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/users"

payload = "<REQUEST BODY>"
headers = {
    'Authorization': 'Bearer <TOKEN>',
    'Content-Type': 'application/json',
    }

response = requests.request("POST", url, data=payload, headers=headers)

print(response.text)
package main

import (
  "fmt"
  "strings"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/users"

  payload := strings.NewReader("<REQUEST BODY>")

  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, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))

}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
   "Content-Type": "application/json",
]
let parameters = <REQUEST BODY> as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(
  url: NSURL(string: "https://rest.tsheets.com/api/v1/users")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest,
  completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');
$client->addHeader('Content-Type', 'application/json');

$req = '<REQUEST BODY>';

$url="https://rest.tsheets.com/api/v1/users"; 

$client->POST($url, $req);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "users": {
      "1": {
        "_status_code": 200,
        "_status_message": "Created",
        "id": 947725,
        "first_name": "Joni",
        "last_name": "Smith",
        "group_id": 0,
        "active": true,
        "employee_number": 0,
        "salaried": false,
        "exempt": false,
        "username": "joni",
        "email": "",
        "email_verified": false,
        "payroll_id": "",
        "hire_date": "0000-00-00",
        "term_date": "0000-00-00",
        "last_modified": "2018-03-28T20:16:44+00:00",
        "last_active": "",
        "created": "2018-03-28T20:16:44+00:00",
        "client_url": "api_sample_output",
        "company_name": "API Sample Output Company",
        "profile_image_url": "",
        "display_name": "",
        "mobile_number": "",
        "pto_balances": {
          "2624351": 0,
          "2624353": 0,
          "2624355": 0
        },
        "submitted_to": "2000-01-01",
        "approved_to": "2000-01-01",
        "manager_of_group_ids": [ ],
        "require_password_change": true,
        "pay_rate": 0,
        "pay_interval": "hour",
        "permissions": {
          "admin": false,
          "mobile": true,
          "status_box": false,
          "reports": false,
          "manage_timesheets": false,
          "manage_authorization": false,
          "manage_users": false,
          "manage_my_timesheets": false,
          "manage_jobcodes": false,
          "pin_login": false,
          "approve_timesheets": false,
          "manage_schedules": false,
          "external_access": false,
          "manage_my_schedule": false,
          "manage_company_schedules": false,
          "view_company_schedules": false,
          "view_group_schedules": false,
          "manage_no_schedules": false,
          "view_my_schedules": false,
          "time_tracking": false
        },
        "customfields": ""
      },
      "2": {
        "_status_code": 200,
        "_status_message": "Created",
        "id": 947727,
        "first_name": "Frank",
        "last_name": "Church",
        "group_id": 0,
        "active": true,
        "employee_number": 0,
        "salaried": false,
        "exempt": false,
        "username": "frank",
        "email": "",
        "email_verified": false,
        "payroll_id": "",
        "hire_date": "0000-00-00",
        "term_date": "0000-00-00",
        "last_modified": "2018-03-28T20:16:44+00:00",
        "last_active": "",
        "created": "2018-03-28T20:16:44+00:00",
        "client_url": "api_sample_output",
        "company_name": "API Sample Output Company",
        "profile_image_url": "",
        "display_name": "",
        "mobile_number": "",
        "pto_balances": {
          "2624351": 0,
          "2624353": 0,
          "2624355": 0
        },
        "submitted_to": "2000-01-01",
        "approved_to": "2000-01-01",
        "manager_of_group_ids": [ ],
        "require_password_change": true,
        "pay_rate": 0,
        "pay_interval": "hour",
        "permissions": {
          "admin": false,
          "mobile": true,
          "status_box": false,
          "reports": false,
          "manage_timesheets": false,
          "manage_authorization": false,
          "manage_users": false,
          "manage_my_timesheets": false,
          "manage_jobcodes": false,
          "pin_login": false,
          "approve_timesheets": false,
          "manage_schedules": false,
          "external_access": false,
          "manage_my_schedule": false,
          "manage_company_schedules": false,
          "view_company_schedules": false,
          "view_group_schedules": false,
          "manage_no_schedules": false,
          "view_my_schedules": false,
          "time_tracking": false
        },
        "customfields": ""
      }
    }
  },
  "supplemental_data": {
    "jobcodes": {
      "2624351": {
        "id": 2624351,
        "parent_id": 0,
        "assigned_to_all": true,
        "billable": false,
        "active": true,
        ...
      },
      "2624353": {
        "id": 2624353,
        "parent_id": 0,
        "assigned_to_all": true,
        "billable": false,
        "active": true,
        ...
      },
      "2624355": {
        "id": 2624355,
        "parent_id": 0,
        "assigned_to_all": true,
        "billable": false,
        "active": true,
        ...
      }
    }
  }
}

Add one or more users to your company.

HTTP Request

posthttps://rest.tsheets.com/api/v1/users

Properties

Pass an array of user objects as the value to a 'data' property (see example).

username
required
String Username that will be used by the employee to log on to TSheets.
first_name
required
String First name of the employee.
last_name
required
String Last name of the employee.

For a full list of properties that may be set on a user, see the User object.

Status Codes

Each user that is created will come back with a _status_code and _status_message that will indicate whether the user was created successfully. If there was a problem creating a user, there may also be an additional field, _status_extra, which will contain more details about the failure.

200 OK. User was created successfully.
417 Expectation Failed. Something was wrong or missing with the properties supplied for this user. See the _status_extra value for more detail.

Update Users

Example: Change the last name for each of these employees, and add the mobile permission to the second one.

Request Body

{
  "data": [
    {
      "id": "933849",
      "first_name": "Mary",
      "last_name": "Samsonite"
    },
    {
      "username": "nancysmith",
      "permissions": {
        "mobile": true
      }
    }
  ]
}

Request

curl -X PUT \
  https://rest.tsheets.com/api/v1/users \
  -H 'Authorization: Bearer <TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '<REQUEST BODY>'
var client = new RestClient("https://rest.tsheets.com/api/v1/users");
var request = new RestRequest(Method.PUT);
request.AddHeader("Authorization", "Bearer <TOKEN>");
request.AddHeader("Content-Type", "application/json");
IRestResponse response = client.Execute(request);
Dim client = New RestClient("https://rest.tsheets.com/api/v1/users")
Dim request = New RestRequest(Method.PUT)
request.AddHeader("Authorization", "Bearer <TOKEN>")
request.AddHeader("Content-Type", "application/json")
Dim response As IRestResponse = client.Execute(request)
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<REQUEST BODY>");
Request request = new Request.Builder()
  .url("https://rest.tsheets.com/api/v1/users")
  .put(body)
  .addHeader("Authorization", "Bearer <TOKEN>")
  .addHeader("Content-Type", "application/json")
  .build();

Response response = client.newCall(request).execute();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://rest.tsheets.com/api/v1/users?limit=30&last_name=sm*",
  "method": "PUT",
  "headers": {
    "Authorization", "Bearer <TOKEN>",
    "Content-Type", "application/json",
  },
  "processData": false,
  "data": "<REQUEST BODY>"
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'PUT',
  url: 'https://rest.tsheets.com/api/v1/users',
  headers: 
  { 
     'Authorization': 'Bearer <TOKEN>',
     'Content-Type': 'application/json',
  },
  body: '<REQUEST BODY>',
  json: true };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
<?php

$request = new HttpRequest();
$request->setUrl('https://rest.tsheets.com/api/v1/users');
$request->setMethod(HTTP_METH_PUT);

$request->setHeaders(array(
  'Authorization' => 'Bearer <TOKEN>',
  'Content-Type' => 'application/json',
));

$request->setBody('<REQUEST BODY>');

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
require 'uri'
require 'net/http'

url = URI("https://rest.tsheets.com/api/v1/users")

http = Net::HTTP.new(url.host, url.port)

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <TOKEN>',
request["Content-Type"] = 'application/json',
request.body = "<REQUEST BODY>"

response = http.request(request)
puts response.read_body
import requests

url = "https://rest.tsheets.com/api/v1/users"

payload = "<REQUEST BODY>"
headers = {
    'Authorization': 'Bearer <TOKEN>',
    'Content-Type': 'application/json',
    }

response = requests.request("PUT", url, data=payload, headers=headers)

print(response.text)
package main

import (
  "fmt"
  "strings"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://rest.tsheets.com/api/v1/users"

  payload := strings.NewReader("<REQUEST BODY>")

  req, _ := http.NewRequest("PUT", 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, _ := ioutil.ReadAll(res.Body)

  fmt.Println(res)
  fmt.Println(string(body))

}
import Foundation

let headers = [
   "Authorization": "Bearer <TOKEN>",
   "Content-Type": "application/json",
]
let parameters = <REQUEST BODY> as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(
  url: NSURL(string: "http://rest.tsheets.com/api/v1/users")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)

request.httpMethod = "PUT"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(
  with: request as URLRequest,
  completionHandler: {
    (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  }
)

dataTask.resume()
use REST::Client;

my $client = REST::Client->new();

$client->addHeader('Authorization', 'Bearer <TOKEN>');
$client->addHeader('Content-Type', 'application/json');

$req = '<REQUEST BODY>';

$url="http://rest.tsheets.com/api/v1/users"; 

$client->PUT($url, $req);
print $client->responseContent();
print $client->responseHeader('ResponseHeader');

Response Format

200 OK

{
  "results": {
    "users": {
      "1": {
        "_status_code": 200,
        "_status_message": "Updated",
        "id": 933849,
        "first_name": "Mary",
        "last_name": "Samsonite",
        "group_id": 0,
        "active": true,
        "employee_number": 0,
        "salaried": false,
        "exempt": false,
        "username": "admin",
        "email": "admin@example.com",
        "email_verified": false,
        "payroll_id": "",
        "hire_date": "0000-00-00",
        "term_date": "0000-00-00",
        "last_modified": "2018-03-28T17:24:20+00:00",
        "last_active": "",
        "created": "2018-03-27T16:13:34+00:00",
        "client_url": "api_sample_output",
        "company_name": "API Sample Output Company",
        "profile_image_url": "https:\/\/www.gravatar.com\/avatar\/e64c7d89f26bd1972efa854d13d7dd61",
        "display_name": "",
        "mobile_number": "2087231456",
        "pto_balances": {
          "2624351": 0,
          "2624353": 0,
          "2624355": 0
        },
        "submitted_to": "2000-01-01",
        "approved_to": "2000-01-01",
        "manager_of_group_ids": [

        ],
        "require_password_change": false,
        "pay_rate": 0,
        "pay_interval": "hour",
        "permissions": {
          "admin": true,
          "mobile": true,
          "status_box": false,
          "reports": false,
          "manage_timesheets": false,
          "manage_authorization": false,
          "manage_users": false,
          "manage_my_timesheets": false,
          "manage_jobcodes": false,
          "pin_login": false,
          "approve_timesheets": false,
          "manage_schedules": false,
          "external_access": false,
          "manage_my_schedule": false,
          "manage_company_schedules": false,
          "view_company_schedules": false,
          "view_group_schedules": false,
          "manage_no_schedules": false,
          "view_my_schedules": false,
          "time_tracking": false
        },
        "customfields": ""
      },
      "2": {
        "_status_code": 200,
        "_status_message": "Updated",
        "id": 933837,
        "first_name": "Nancy",
        "last_name": "Smith",
        "group_id": 64965,
        "active": true,
        "employee_number": 0,
        "salaried": false,
        "exempt": false,
        "username": "nancysmith",
        "email": "",
        "email_verified": false,
        "payroll_id": "",
        "hire_date": "0000-00-00",
        "term_date": "0000-00-00",
        "last_modified": "2018-03-28T20:16:46+00:00",
        "last_active": "2018-03-28T20:16:39+00:00",
        "created": "2018-03-27T16:13:30+00:00",
        "client_url": "api_sample_output",
        "company_name": "API Sample Output Company",
        "profile_image_url": "",
        "display_name": "",
        "mobile_number": "",
        "pto_balances": {
          "2624351": 0,
          "2624353": 0,
          "2624355": 0
        },
        "submitted_to": "2000-01-01",
        "approved_to": "2000-01-01",
        "manager_of_group_ids": [

        ],
        "require_password_change": false,
        "pay_rate": 0,
        "pay_interval": "hour",
        "permissions": {
          "admin": false,
          "mobile": true,
          "status_box": false,
          "reports": false,
          "manage_timesheets": false,
          "manage_authorization": false,
          "manage_users": false,
          "manage_my_timesheets": false,
          "manage_jobcodes": false,
          "pin_login": false,
          "approve_timesheets": false,
          "manage_schedules": false,
          "external_access": false,
          "manage_my_schedule": false,
          "manage_company_schedules": false,
          "view_company_schedules": false,
          "view_group_schedules": false,
          "manage_no_schedules": false,
          "view_my_schedules": false,
          "time_tracking": false
        },
        "customfields": ""
      }
    }
  },
  "supplemental_data": {
    "jobcodes": {
      "2624351": {
        "id": 2624351,
        "parent_id": 0,
        "assigned_to_all": true,
        "billable": false,
        "active": true,
        "type": "pto",
        ...
      },
      "2624353": {
        "id": 2624353,
        "parent_id": 0,
        "assigned_to_all": true,
        "billable": false,
        "active": true,
        "type": "pto",
        ...
      },
      "2624355": {
        "id": 2624355,
        "parent_id": 0,
        "assigned_to_all": true,
        "billable": false,
        "active": true,
        "type": "pto",
        ...
      }
    },
    "groups": {
      "64965": {
        "id": 64965,
        "active": true,
        "name": "Construction",
        ...
      }
    }
  }
}


Edit one or more users in your company. The batch of user updates is passed as a JSON string in the body of the HTTP request. If the value passed in is the same as it was previously, or if a particular property is not passed in at all, it will be ignored.

HTTP Request

puthttps://rest.tsheets.com/api/v1/users

Properties

Pass an array of user objects as the value to a 'data' property (see example).

id
required
Int Id of the user to update.

OR

username
required
String Username of the user to update.

All other properties defined on a user object may be passed in to the request with a new value in order to change it. If the value passed in is the same as it was previously, or if a particular property is not passed in at all, it will be ignored.

Status Codes

Each user that is edited will come back with a _status_code and _status_message that will indicate whether the user was edited successfully. If there was a problem editing a user, there may also be an additional field, _status_extra, which will contain more details about the failure.

200 OK. User was edited successfully.
417 Expectation Failed. Something was wrong or missing with the properties supplied for this user. See the _status_extra value for more detail.

Changelog

Date Description
2019-03-17 Initial Content Creation
2019-03-19 Updated code examples for Effective Settings
2019-04-15 Fixing incorrect authentication examples
2019-05-22 Fixing access modifier on Users email_verified
2019-05-23 Property created is required on Geolocation create
2019-05-29 Adding GitHub link, fixing reports examples & minor typos
2019-05-30 Adjusting layout to support portrait mode
2019-05-30 Public documentation for Invitations endpoint
2019-06-10 Fix help@tsheets.com link under the "Getting Help" section
2019-06-10 Publication of docs for CustomFieldItemFilters, CustomFieldItemUserFilters, and CustomFieldItemJobcodeFilters
2019-07-01 Fixing data type of accuracy Geolocation property to be a float
2019-07-16 Fixing incorrect Invitations example
2019-08-12 Updating support links
2019-09-04 Adding the 'name' filter to the job codes GET operation
2019-09-23 Updating code templates to allow overriding base URL and headers.
2019-10-03 Updated code examples for Effective Settings to add two_way_sync_enabled_for_user setting
2019-11-19 Adding the 'name' filter to the custom field items GET operation
2019-12-17 Adding sections for 'Create Custom Fields' and 'Update Custom Fields'
2020-03-03 Correcting the expiration time in the OAuth refresh examples
2020-03-04 Removing non-existent 'created' property from the Custom Field Item Object
2020-03-18 Explaining restriction on 'show_to_all' attribute on custom fields
2020-03-18 Adding the customfields object to the jobcode entities and a new customfields query param to the /jobcodes endpoint
2020-03-18 Updated notes for user fields 'display_name' and 'pronouns' as they are no longer null in any case
2020-03-24 Updated notes for request throttling from 10 minute to 5 minute throttling window
2020-05-13 Published Time Off Requests documentation
2020-06-17 Updating request formats to make response code documentation more accurate.
2020-10-19 Remove employee_number from list of private fields
2020-11-24 Adding documentation for time_tracking permission
2021-01-15 Adding documentation for Jobcode connect_with_quickbooks property
2021-05-17 Adding new rebranded images, update text and addressed sidebar for same look and feel as QuickBooks
2021-08-24 Documenting the active_users parameter exposed in the schedule_events endpoint
2022-04-26 Remove pronouns from user object as field has been merged with display_name
2022-05-16 Documenting PUT and POST verbs for CustomFieldItemFilters
2022-05-31 Adding sections for 'Estimate Items', 'Estimates', 'Projects', 'Project Activity', 'Project Activity Read Times', 'Project Activity Replies', and 'Project Notes'
2022-05-31 Adding 'Project Estimate' and 'Project Estimate Detail' to the 'Reports' section
2022-10-25 Adding expected error response for 'Duplicate entry' in 'Update Reminders' section
2022-10-27 Updating 'Getting Help' resource links
2023-10-19 Deprecated per_page and added limit which supercedes per_page